[{"data":1,"prerenderedAt":2118},["ShallowReactive",2],{"docs-navigation":3,"docs\u002Fdocs\u002Freference\u002Fagent-install-stack":194,"docs\u002Fdocs\u002Freference\u002Fagent-install-stack-surround":2115},[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":2108,"extension":2109,"meta":2110,"navigation":2111,"path":191,"seo":2112,"stem":192,"verified":2113,"__hash__":2114},"docs\u002Fdocs\u002F5.reference\u002F7.agent-install-stack.md","Install the AgentFeedback stack (for agents)",{"type":198,"value":199,"toc":2096},"minimark",[200,233,236,244,285,290,298,352,356,359,381,384,443,461,466,538,542,574,692,769,773,849,853,865,884,899,935,939,1032,1036,1039,1150,1184,1224,1236,1240,1285,1289,1296,1344,1347,1364,1370,1409,1451,1476,1480,1550,1554,1566,1595,1618,1641,1645,1701,1705,1719,1736,1763,1767,1813,1817,1830,1849,1871,1904,2059,2075,2092],[201,202,203,204,211,212,215,216,220,221,224,225,228,229,232],"p",{},"You are an AI agent asked to install the AgentFeedback server and client on\nthe machine you run on, and to verify reporting end to end. This file\nincludes the client playbook, ",[205,206,207],"a",{"href":186},[208,209,210],"code",{},"AGENT-INSTALL.md",": a step\nnamed \"client step N\" is step N of that file, run exactly as written there,\nwith its own outcome. Fetch it from the same repository and revision as this\nfile. Follow this file top to bottom; it uses the client playbook's format:\nevery step has one command in an ",[208,213,214],{},"sh"," block, one ",[217,218,219],"strong",{},"Verify"," line, and one\n",[217,222,223],{},"Outcome"," in a ",[208,226,227],{},"json"," block that you fill in and quote back to the human\nbefore you go on. A step that does not apply to you still gets its outcome,\nwith ",[208,230,231],{},"\"status\": \"skipped\""," and the reason.",[201,234,235],{},"This file describes release 4.0.0 and later. The server runs on Linux (a\nsystemd user unit) or macOS (a launchd agent), or in Docker Compose on\neither; not on Windows. The server and the client end up on this machine;\nother machines join later with the client playbook.",[201,237,238,239,243],{},"This stack serves the base API, not hosted canonical issue aggregation.\nInstalling a newer client does not add those server routes. For that\nseparate, capability-gated workflow, use\n",[205,240,242],{"href":241},"\u002Fdocs\u002Freference\u002Foperate#canonical-issues","Canonical issues","; do not change the stack\nor select another destination to make an unsupported operation succeed.",[201,245,246,247,250,251,254,255,258,259,262,263,265,266,254,269,272,273,276,277,280,281,284],{},"Placeholders, beyond the client playbook's: ",[208,248,249],{},"\u003Ckey_file>",",\n",[208,252,253],{},"\u003Cenv_file>"," and ",[208,256,257],{},"\u003Clisten>"," come from step S1's outcome, ",[208,260,261],{},"\u003Cport>"," is the\nport of ",[208,264,257],{},", ",[208,267,268],{},"\u003Cpath>",[208,270,271],{},"next"," come from step S2's outcome, and\n",[208,274,275],{},"\u003CURL>"," is set in step S5. Replace them before you run a command. The\nplaybook gate answers step S4's exposure (",[208,278,279],{},"AF_PLAYBOOK_ADDRESS"," for\n",[208,282,283],{},"\u003Caddress>",") as the client playbook describes; never read that variable,\nask the human.",[286,287,289],"h2",{"id":288},"safety-rules","Safety rules",[201,291,292,293,297],{},"The client playbook's ",[205,294,296],{"href":295},"\u002Fdocs\u002Freference\u002Fagent-install#safety-rules","safety rules"," hold for\nthis whole file. On top of them:",[299,300,301,321,331],"ul",{},[302,303,304,307,308,265,311,314,315,317,318,320],"li",{},[217,305,306],{},"The server key never enters your context."," Step S1's command removes it\nfrom the output, and the client reads it from the key file on stdin (step\nS5). Never ",[208,309,310],{},"cat",[208,312,313],{},"grep"," or open ",[208,316,249],{}," with a file tool.\n",[208,319,253],{}," names the key file and holds no key; reading it is safe.",[302,322,323,330],{},[217,324,325,326,329],{},"The server listens on ",[208,327,328],{},"127.0.0.1"," until the human decides otherwise"," in\nstep S4. Change the listen address or the published port only as step S4\nsays, after the human's explicit yes. Never touch a firewall, a reverse\nproxy or a tunnel: those are the human's.",[302,332,333,340,341,344,345,348,349,351],{},[217,334,335,336,339],{},"Never add ",[208,337,338],{},"--force"," on your own."," On ",[208,342,343],{},"serve --init"," it rotates the key\nand cuts off every client; on ",[208,346,347],{},"server install"," it replaces a service file.\nBoth need the human's word; an explicit yes in step S4 is that word for\nthe one ",[208,350,338],{}," step S4 names.",[286,353,355],{"id":354},"step-s0-the-client-binary","Step S0: The client binary",[201,357,358],{},"Run client step 0. Then:",[299,360,361,364,374],{},[302,362,363],{},"A chat app (no shell) cannot run a server: tell the human, and explain the\nclient side with client step 2.8.",[302,365,366,369,370,373],{},[208,367,368],{},"binary_possible"," false, or Windows: stop and tell the human. The server is\nthe ",[208,371,372],{},"agentfeedback"," binary.",[302,375,376,377,380],{},"Otherwise skip client step 1 (the server does not exist yet) and run client\nstep 2.1. Its ",[208,378,379],{},"\u003Cbinary>"," runs the server as well as the client.",[201,382,383],{},"Then check who you run as, and whether Docker Compose is usable, for step S2:",[385,386,390],"pre",{"className":387,"code":388,"language":214,"meta":389,"style":389},"language-sh shiki shiki-themes github-light github-light github-dark","id -un; docker compose version && docker info --format '{{.ServerVersion}}' || echo 'compose: not usable'\n","",[208,391,392],{"__ignoreMap":389},[393,394,397,401,405,409,412,416,419,422,424,427,430,433,437,440],"span",{"class":395,"line":396},"line",1,[393,398,400],{"class":399},"snPdu","id",[393,402,404],{"class":403},"sBjJW"," -un",[393,406,408],{"class":407},"sxrX7","; ",[393,410,411],{"class":399},"docker",[393,413,415],{"class":414},"sIIMD"," compose",[393,417,418],{"class":414}," version",[393,420,421],{"class":407}," && ",[393,423,411],{"class":399},[393,425,426],{"class":414}," info",[393,428,429],{"class":403}," --format",[393,431,432],{"class":414}," '{{.ServerVersion}}'",[393,434,436],{"class":435},"s8jYJ"," ||",[393,438,439],{"class":403}," echo",[393,441,442],{"class":414}," 'compose: not usable'\n",[201,444,445,448,449,452,453,456,457,460],{},[217,446,447],{},"Verify:"," client steps 0 and 2.1 report ",[208,450,451],{},"\"status\": \"ok\"",". The first line\nis the user the server will belong to; ",[208,454,455],{},"root"," means stop and ask the human\nto run this file as the user who should own the server (a systemd user unit\nrefuses root, and files written as root are unreadable to that user).\nCompose is usable when both later lines succeed; a last line ",[208,458,459],{},"compose: not usable"," means it is not, which is not a failure.",[201,462,463],{},[217,464,465],{},"Outcome:",[385,467,470],{"className":468,"code":469,"language":227,"meta":389,"style":389},"language-json shiki shiki-themes github-light github-light github-dark","{\"step\": \"S0\", \"status\": \"ok\", \"user\": \"user\", \"os\": \"linux\", \"binary\": \"\u002Fhome\u002Fuser\u002F.local\u002Fbin\u002Fagentfeedback\", \"compose\": false}\n",[208,471,472],{"__ignoreMap":389},[393,473,474,477,480,483,486,488,491,493,496,498,501,503,505,507,510,512,515,517,520,522,525,527,530,532,535],{"class":395,"line":396},[393,475,476],{"class":407},"{",[393,478,479],{"class":403},"\"step\"",[393,481,482],{"class":407},": ",[393,484,485],{"class":414},"\"S0\"",[393,487,265],{"class":407},[393,489,490],{"class":403},"\"status\"",[393,492,482],{"class":407},[393,494,495],{"class":414},"\"ok\"",[393,497,265],{"class":407},[393,499,500],{"class":403},"\"user\"",[393,502,482],{"class":407},[393,504,500],{"class":414},[393,506,265],{"class":407},[393,508,509],{"class":403},"\"os\"",[393,511,482],{"class":407},[393,513,514],{"class":414},"\"linux\"",[393,516,265],{"class":407},[393,518,519],{"class":403},"\"binary\"",[393,521,482],{"class":407},[393,523,524],{"class":414},"\"\u002Fhome\u002Fuser\u002F.local\u002Fbin\u002Fagentfeedback\"",[393,526,265],{"class":407},[393,528,529],{"class":403},"\"compose\"",[393,531,482],{"class":407},[393,533,534],{"class":403},"false",[393,536,537],{"class":407},"}\n",[286,539,541],{"id":540},"step-s1-the-server-configuration","Step S1: The server configuration",[201,543,544,546,547,482,550,553,554,557,558,561,562,565,566,569,570,573],{},[208,545,343],{}," writes two files, both readable by the owner only, into\n",[208,548,549],{},"~\u002F.config\u002Fagentfeedback\u002Fserver",[208,551,552],{},"api-key",", a new random key, and\n",[208,555,556],{},"serve.env",", which names the key file, the database\n(",[208,559,560],{},"~\u002F.local\u002Fshare\u002Fagentfeedback\u002Fagentfeedback.db",") and the listen address\n",[208,563,564],{},"127.0.0.1:8090",". It starts nothing. Its JSON outcome is the only place the\nkey is printed, so the ",[208,567,568],{},"sed"," drops that member before you see it. The ",[208,571,572],{},"curl","\nfirst checks what answers on port 8090.",[385,575,577],{"className":387,"code":576,"language":214,"meta":389,"style":389},"c=$(curl -s -o \u002Fdev\u002Fnull -m 3 -w '%{http_code}' http:\u002F\u002F127.0.0.1:8090\u002Fapi\u002Fv1\u002Fmeta); case \"$c\" in 000) \"\u003Cbinary>\" serve --init | sed 's\u002F,\"api_key\":\"[^\"]*\"\u002F\u002F' ;; 401) echo 'an AgentFeedback server already answers on port 8090' ;; *) echo \"port 8090 is in use (HTTP $c)\" ;; esac\n",[208,578,579],{"__ignoreMap":389},[393,580,581,584,587,590,592,595,598,601,604,607,610,613,616,619,622,625,628,631,634,638,641,644,647,650,653,656,659,662,665,667,669,672,674,677,679,682,684,687,689],{"class":395,"line":396},[393,582,583],{"class":407},"c",[393,585,586],{"class":435},"=",[393,588,589],{"class":407},"$(",[393,591,572],{"class":399},[393,593,594],{"class":403}," -s",[393,596,597],{"class":403}," -o",[393,599,600],{"class":414}," \u002Fdev\u002Fnull",[393,602,603],{"class":403}," -m",[393,605,606],{"class":403}," 3",[393,608,609],{"class":403}," -w",[393,611,612],{"class":414}," '%{http_code}'",[393,614,615],{"class":414}," http:\u002F\u002F127.0.0.1:8090\u002Fapi\u002Fv1\u002Fmeta",[393,617,618],{"class":407},"); ",[393,620,621],{"class":435},"case",[393,623,624],{"class":414}," \"",[393,626,627],{"class":407},"$c",[393,629,630],{"class":414},"\"",[393,632,633],{"class":435}," in",[393,635,637],{"class":636},"s3JiQ"," 000",[393,639,640],{"class":435},")",[393,642,643],{"class":399}," \"\u003Cbinary>\"",[393,645,646],{"class":414}," serve",[393,648,649],{"class":403}," --init",[393,651,652],{"class":435}," |",[393,654,655],{"class":399}," sed",[393,657,658],{"class":414}," 's\u002F,\"api_key\":\"[^\"]*\"\u002F\u002F'",[393,660,661],{"class":407}," ;; ",[393,663,664],{"class":636},"401",[393,666,640],{"class":435},[393,668,439],{"class":403},[393,670,671],{"class":414}," 'an AgentFeedback server already answers on port 8090'",[393,673,661],{"class":407},[393,675,676],{"class":435},"*)",[393,678,439],{"class":403},[393,680,681],{"class":414}," \"port 8090 is in use (HTTP ",[393,683,627],{"class":407},[393,685,686],{"class":414},")\"",[393,688,661],{"class":407},[393,690,691],{"class":435},"esac\n",[201,693,694,696,697,265,700,250,703,265,706,265,709,254,712,715,716,719,720,723,724,727,728,731,732,735,736,738,739,742,743,745,746,727,748,750,751,754,755,265,758,761,762,254,765,768],{},[217,695,447],{}," the last line is JSON with ",[208,698,699],{},"\"status\":\"written\"",[208,701,702],{},"dir",[208,704,705],{},"key_file",[208,707,708],{},"env_file",[208,710,711],{},"database",[208,713,714],{},"\"listen\":\"127.0.0.1:8090\"",", and no\n",[208,717,718],{},"api_key",". If any output shows a 64-character hex string, the key reached\nyou: tell the human, and after setup they rotate it themselves.\n",[208,721,722],{},"port 8090 is in use"," means something else listens there: ask the human for\na free port and run the command again with that port in both places and\n",[208,725,726],{},"--port \u003CN>"," after ",[208,729,730],{},"--init",". ",[208,733,734],{},"an AgentFeedback server already answers",", or an\nerror naming an existing file, means this machine already has a server: show\nthe human ",[208,737,549],{}," and ask whether to keep it or\nreplace it. Keep: ",[208,740,741],{},"grep -v '^#' ~\u002F.config\u002Fagentfeedback\u002Fserver\u002Fserve.env","\nshows the values for this outcome; step S2 then reports the existing service\nfile, and step S3 finds the server answering. Replace: the same ",[208,744,343],{}," with ",[208,747,338],{},[208,749,730],{},", which rotates the key; after step S2,\nrestart the running server with the restart command of its form (",[208,752,753],{},"next[5]","\nfor ",[208,756,757],{},"systemd",[208,759,760],{},"next[4]"," for ",[208,763,764],{},"launchd",[208,766,767],{},"compose",") in place of step S3's\nstart commands.",[201,770,771],{},[217,772,465],{},[385,774,776],{"className":468,"code":775,"language":227,"meta":389,"style":389},"{\"step\": \"S1\", \"status\": \"ok\", \"dir\": \"\u002Fhome\u002Fuser\u002F.config\u002Fagentfeedback\u002Fserver\", \"key_file\": \"\u002Fhome\u002Fuser\u002F.config\u002Fagentfeedback\u002Fserver\u002Fapi-key\", \"env_file\": \"\u002Fhome\u002Fuser\u002F.config\u002Fagentfeedback\u002Fserver\u002Fserve.env\", \"database\": \"\u002Fhome\u002Fuser\u002F.local\u002Fshare\u002Fagentfeedback\u002Fagentfeedback.db\", \"listen\": \"127.0.0.1:8090\"}\n",[208,777,778],{"__ignoreMap":389},[393,779,780,782,784,786,789,791,793,795,797,799,802,804,807,809,812,814,817,819,822,824,827,829,832,834,837,839,842,844,847],{"class":395,"line":396},[393,781,476],{"class":407},[393,783,479],{"class":403},[393,785,482],{"class":407},[393,787,788],{"class":414},"\"S1\"",[393,790,265],{"class":407},[393,792,490],{"class":403},[393,794,482],{"class":407},[393,796,495],{"class":414},[393,798,265],{"class":407},[393,800,801],{"class":403},"\"dir\"",[393,803,482],{"class":407},[393,805,806],{"class":414},"\"\u002Fhome\u002Fuser\u002F.config\u002Fagentfeedback\u002Fserver\"",[393,808,265],{"class":407},[393,810,811],{"class":403},"\"key_file\"",[393,813,482],{"class":407},[393,815,816],{"class":414},"\"\u002Fhome\u002Fuser\u002F.config\u002Fagentfeedback\u002Fserver\u002Fapi-key\"",[393,818,265],{"class":407},[393,820,821],{"class":403},"\"env_file\"",[393,823,482],{"class":407},[393,825,826],{"class":414},"\"\u002Fhome\u002Fuser\u002F.config\u002Fagentfeedback\u002Fserver\u002Fserve.env\"",[393,828,265],{"class":407},[393,830,831],{"class":403},"\"database\"",[393,833,482],{"class":407},[393,835,836],{"class":414},"\"\u002Fhome\u002Fuser\u002F.local\u002Fshare\u002Fagentfeedback\u002Fagentfeedback.db\"",[393,838,265],{"class":407},[393,840,841],{"class":403},"\"listen\"",[393,843,482],{"class":407},[393,845,846],{"class":414},"\"127.0.0.1:8090\"",[393,848,537],{"class":407},[286,850,852],{"id":851},"step-s2-the-service-file","Step S2: The service file",[201,854,855,856,858,859,861,862,864],{},"The default is a service of the operating system that runs the binary: a\nsystemd user unit on Linux, a launchd agent on macOS. When step S0 found\nDocker Compose, ask the human whether they prefer to run the server in a\ncontainer instead; never pick Compose on your own. ",[208,857,347],{}," writes\nexactly one file from ",[208,860,556],{}," and starts nothing; its outcome's ",[208,863,271],{},"\nlists the commands to start, check, back up and restart the server.",[385,866,868],{"className":387,"code":867,"language":214,"meta":389,"style":389},"\"\u003Cbinary>\" server install --systemd\n",[208,869,870],{"__ignoreMap":389},[393,871,872,875,878,881],{"class":395,"line":396},[393,873,874],{"class":399},"\"\u003Cbinary>\"",[393,876,877],{"class":414}," server",[393,879,880],{"class":414}," install",[393,882,883],{"class":403}," --systemd\n",[201,885,886,887,890,891,894,895,898],{},"On macOS, use ",[208,888,889],{},"--launchd"," in place of ",[208,892,893],{},"--systemd","; for Compose, ",[208,896,897],{},"--compose",".\nCompose 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\ndirectory; there, tell the human and use the default form instead.",[201,900,901,696,903,265,905,265,908,911,912,914,915,917,918,924,925,927,928,930,931,934],{},[217,902,447],{},[208,904,699],{},[208,906,907],{},"mode",[208,909,910],{},"path","\n(the file it wrote) and ",[208,913,271],{},". An error naming an existing file means a\nservice file is already there: show the human the path and ask whether to\nkeep it (go on; ",[208,916,271],{}," is the same for the same form, see\n",[205,919,921],{"href":920},"\u002Fdocs\u002Freference\u002Foperate#bare-binary-no-docker",[208,922,923],{},"docs\u002Foperate.md",") or replace it\n(the same command with ",[208,926,338],{},"). An error about the image means\na binary that is not a release: ",[208,929,897],{}," then needs ",[208,932,933],{},"--image \u003Cref>",", which\nonly the human can name.",[201,936,937],{},[217,938,465],{},[385,940,942],{"className":468,"code":941,"language":227,"meta":389,"style":389},"{\"step\": \"S2\", \"status\": \"ok\", \"mode\": \"systemd\", \"path\": \"\u002Fhome\u002Fuser\u002F.config\u002Fsystemd\u002Fuser\u002Fagentfeedback.service\", \"next\": [\"systemctl --user daemon-reload\", \"systemctl --user enable --now agentfeedback.service\", \"systemctl --user status agentfeedback.service\", \"loginctl enable-linger \\\"$USER\\\"\", \"set -a; . \u002Fhome\u002Fuser\u002F.config\u002Fagentfeedback\u002Fserver\u002Fserve.env; set +a; \u002Fhome\u002Fuser\u002F.local\u002Fbin\u002Fagentfeedback backup \u002Fhome\u002Fuser\u002F.local\u002Fshare\u002Fagentfeedback\u002Fagentfeedback-$(date -u +%Y%m%dT%H%M%SZ).db\", \"systemctl --user restart agentfeedback.service\"]}\n",[208,943,944],{"__ignoreMap":389},[393,945,946,948,950,952,955,957,959,961,963,965,968,970,973,975,978,980,983,985,988,991,994,996,999,1001,1004,1006,1009,1012,1015,1017,1019,1021,1024,1026,1029],{"class":395,"line":396},[393,947,476],{"class":407},[393,949,479],{"class":403},[393,951,482],{"class":407},[393,953,954],{"class":414},"\"S2\"",[393,956,265],{"class":407},[393,958,490],{"class":403},[393,960,482],{"class":407},[393,962,495],{"class":414},[393,964,265],{"class":407},[393,966,967],{"class":403},"\"mode\"",[393,969,482],{"class":407},[393,971,972],{"class":414},"\"systemd\"",[393,974,265],{"class":407},[393,976,977],{"class":403},"\"path\"",[393,979,482],{"class":407},[393,981,982],{"class":414},"\"\u002Fhome\u002Fuser\u002F.config\u002Fsystemd\u002Fuser\u002Fagentfeedback.service\"",[393,984,265],{"class":407},[393,986,987],{"class":403},"\"next\"",[393,989,990],{"class":407},": [",[393,992,993],{"class":414},"\"systemctl --user daemon-reload\"",[393,995,265],{"class":407},[393,997,998],{"class":414},"\"systemctl --user enable --now agentfeedback.service\"",[393,1000,265],{"class":407},[393,1002,1003],{"class":414},"\"systemctl --user status agentfeedback.service\"",[393,1005,265],{"class":407},[393,1007,1008],{"class":414},"\"loginctl enable-linger ",[393,1010,1011],{"class":403},"\\\"",[393,1013,1014],{"class":414},"$USER",[393,1016,1011],{"class":403},[393,1018,630],{"class":414},[393,1020,265],{"class":407},[393,1022,1023],{"class":414},"\"set -a; . \u002Fhome\u002Fuser\u002F.config\u002Fagentfeedback\u002Fserver\u002Fserve.env; set +a; \u002Fhome\u002Fuser\u002F.local\u002Fbin\u002Fagentfeedback backup \u002Fhome\u002Fuser\u002F.local\u002Fshare\u002Fagentfeedback\u002Fagentfeedback-$(date -u +%Y%m%dT%H%M%SZ).db\"",[393,1025,265],{"class":407},[393,1027,1028],{"class":414},"\"systemctl --user restart agentfeedback.service\"",[393,1030,1031],{"class":407},"]}\n",[286,1033,1035],{"id":1034},"step-s3-start-the-server","Step S3: Start the server",[201,1037,1038],{},"Start it and wait until it answers. As in client step 1, no key is sent, so\nan AgentFeedback server must refuse:",[385,1040,1042],{"className":387,"code":1041,"language":214,"meta":389,"style":389},"systemctl --user daemon-reload && systemctl --user enable --now agentfeedback.service && for i in 1 2 3 4 5 6 7 8 9 10; do curl -sS -m 2 -w '\\n%{http_code}\\n' 'http:\u002F\u002F\u003Clisten>\u002Fapi\u002Fv1\u002Fmeta' && break; sleep 1; done\n",[208,1043,1044],{"__ignoreMap":389},[393,1045,1046,1049,1052,1055,1057,1059,1061,1064,1067,1070,1072,1075,1078,1081,1084,1087,1089,1092,1095,1098,1101,1104,1107,1110,1112,1115,1118,1121,1123,1125,1127,1130,1133,1135,1138,1140,1143,1145,1147],{"class":395,"line":396},[393,1047,1048],{"class":399},"systemctl",[393,1050,1051],{"class":403}," --user",[393,1053,1054],{"class":414}," daemon-reload",[393,1056,421],{"class":407},[393,1058,1048],{"class":399},[393,1060,1051],{"class":403},[393,1062,1063],{"class":414}," enable",[393,1065,1066],{"class":403}," --now",[393,1068,1069],{"class":414}," agentfeedback.service",[393,1071,421],{"class":407},[393,1073,1074],{"class":435},"for",[393,1076,1077],{"class":407}," i ",[393,1079,1080],{"class":435},"in",[393,1082,1083],{"class":414}," 1",[393,1085,1086],{"class":414}," 2",[393,1088,606],{"class":414},[393,1090,1091],{"class":414}," 4",[393,1093,1094],{"class":414}," 5",[393,1096,1097],{"class":414}," 6",[393,1099,1100],{"class":414}," 7",[393,1102,1103],{"class":414}," 8",[393,1105,1106],{"class":414}," 9",[393,1108,1109],{"class":414}," 10",[393,1111,408],{"class":407},[393,1113,1114],{"class":435},"do",[393,1116,1117],{"class":399}," curl",[393,1119,1120],{"class":403}," -sS",[393,1122,603],{"class":403},[393,1124,1086],{"class":403},[393,1126,609],{"class":403},[393,1128,1129],{"class":414}," '\\n%{http_code}\\n'",[393,1131,1132],{"class":414}," 'http:\u002F\u002F\u003Clisten>\u002Fapi\u002Fv1\u002Fmeta'",[393,1134,421],{"class":407},[393,1136,1137],{"class":435},"break",[393,1139,408],{"class":407},[393,1141,1142],{"class":399},"sleep",[393,1144,1083],{"class":403},[393,1146,408],{"class":407},[393,1148,1149],{"class":435},"done\n",[201,1151,1152,1153,1155,1156,1158,1159,1162,1163,1166,1167,254,1170,1173,1174,1176,1177,1179,1180,1183],{},"For ",[208,1154,764],{},", replace the two ",[208,1157,1048],{}," commands with ",[208,1160,1161],{},"next[0]"," and\n",[208,1164,1165],{},"next[1]"," from step S2 (",[208,1168,1169],{},"launchctl bootstrap …",[208,1171,1172],{},"launchctl kickstart …",");\nfor ",[208,1175,767],{},", with ",[208,1178,1161],{}," (",[208,1181,1182],{},"docker compose -f \u003Cpath> up -d",").",[201,1185,1186,1188,1189,1191,1192,1195,1196,1199,1200,761,1203,254,1205,265,1207,280,1209,1211,1212,1215,1216,1219,1220,1223],{},[217,1187,447],{}," the last line is ",[208,1190,664],{}," and the line before it is JSON with\n",[208,1193,1194],{},"\"error\":\"unauthorized\""," and a message naming ",[208,1197,1198],{},"X-Api-Key",". Anything else:\nrun the status command (",[208,1201,1202],{},"next[2]",[208,1204,757],{},[208,1206,764],{},[208,1208,1165],{},[208,1210,767],{},"), read the server's log (",[208,1213,1214],{},"journalctl --user -u agentfeedback.service -n 50 --no-pager",", the end of\n",[208,1217,1218],{},"~\u002FLibrary\u002FLogs\u002Fagentfeedback\u002Fserve.log",", or ",[208,1221,1222],{},"docker compose -f \u003Cpath> logs --tail 50 agentfeedback","), and show the human both.",[201,1225,1226,1227,1229,1230,1179,1233,1183],{},"With ",[208,1228,757],{},", the user unit stops when the human's last session ends. Ask\nwhether the server should keep running without them logged in; only on yes,\nrun ",[208,1231,1232],{},"loginctl enable-linger \"$USER\"",[208,1234,1235],{},"next[3]",[201,1237,1238],{},[217,1239,465],{},[385,1241,1243],{"className":468,"code":1242,"language":227,"meta":389,"style":389},"{\"step\": \"S3\", \"status\": \"ok\", \"running\": true, \"linger\": false}\n",[208,1244,1245],{"__ignoreMap":389},[393,1246,1247,1249,1251,1253,1256,1258,1260,1262,1264,1266,1269,1271,1274,1276,1279,1281,1283],{"class":395,"line":396},[393,1248,476],{"class":407},[393,1250,479],{"class":403},[393,1252,482],{"class":407},[393,1254,1255],{"class":414},"\"S3\"",[393,1257,265],{"class":407},[393,1259,490],{"class":403},[393,1261,482],{"class":407},[393,1263,495],{"class":414},[393,1265,265],{"class":407},[393,1267,1268],{"class":403},"\"running\"",[393,1270,482],{"class":407},[393,1272,1273],{"class":403},"true",[393,1275,265],{"class":407},[393,1277,1278],{"class":403},"\"linger\"",[393,1280,482],{"class":407},[393,1282,534],{"class":403},[393,1284,537],{"class":407},[286,1286,1288],{"id":1287},"step-s4-ask-the-human-the-four-decisions","Step S4: Ask the human the four decisions",[201,1290,1291,1292,1295],{},"Ask exactly these four questions in one message, and wait for the answers.\nNever assume one: a question left unanswered changes nothing and is recorded\nas ",[208,1293,1294],{},"\"unanswered\"",".",[1297,1298,1299],"blockquote",{},[1300,1301,1302,1315,1321,1334],"ol",{},[302,1303,1304,1307,1308,1310,1311,1314],{},[217,1305,1306],{},"Exposure."," The server listens on ",[208,1309,257],{},", so only this machine\nreaches it. Should other machines reach it too? If so, on which address:\nevery interface (",[208,1312,1313],{},"0.0.0.0",") or one interface's IPv4 address?",[302,1316,1317,1320],{},[217,1318,1319],{},"TLS."," Will a reverse proxy or a tunnel that you run terminate TLS in\nfront of it? Without TLS, every client sends the API key across the\nnetwork in clear text.",[302,1322,1323,1326,1327,1329,1330,1333],{},[217,1324,1325],{},"The key."," It is in ",[208,1328,249],{},", readable by you only, and after the\nnext step also in this machine's client configuration. Where do you want to keep your own copy,\nfor example a password manager? I will not print it; run\n",[208,1331,1332],{},"cat \u003Ckey_file>"," in your own terminal to copy it.",[302,1335,1336,1339,1340,1343],{},[217,1337,1338],{},"Who else gets it."," Which other machines or people should report to\nthis server? They all share this one key, and rotating it\n(",[208,1341,1342],{},"agentfeedback serve --init --force",") cuts every client off until it is\nreconfigured.",[201,1345,1346],{},"Only answer 1 changes what you do, and only when it is an explicit yes with\nan address:",[299,1348,1349,1355,1361],{},[302,1350,1351,1352,1354],{},"A yes together with a reverse proxy or a tunnel on this machine (answer 2)\nneeds no change: it reaches the server on ",[208,1353,328],{},". Setting it up is the\nhuman's.",[302,1356,1357,1358,1360],{},"Any other yes opens a plain-HTTP port. Before changing anything, tell the\nhuman: the server is not safe to expose directly to the internet; the\nport is safe only inside a trusted private network, or behind a TLS proxy\nthat also authenticates; without TLS the key crosses the network in clear\ntext; never bind an address on a public interface; with Compose, Docker\npublishes the port past host firewalls such as ufw. Change the address only\nwhen the human says yes after that warning; that yes also covers the\n",[208,1359,338],{}," below.",[302,1362,1363],{},"An IPv6 address: tell the human this file supports IPv4 addresses only,\nand change nothing.",[201,1365,1366,1367,1369],{},"To change the address, ",[208,1368,283],{}," being the human's answer:",[385,1371,1373],{"className":387,"code":1372,"language":214,"meta":389,"style":389},"sed -i.bak 's\u002F^HTTP_LISTEN_ADDR=127\\.0\\.0\\.1:\u002FHTTP_LISTEN_ADDR=\u003Caddress>:\u002F' '\u003Cenv_file>' && systemctl --user restart agentfeedback.service && grep '^HTTP_LISTEN_ADDR=' '\u003Cenv_file>'\n",[208,1374,1375],{"__ignoreMap":389},[393,1376,1377,1379,1382,1385,1388,1390,1392,1394,1397,1399,1401,1403,1406],{"class":395,"line":396},[393,1378,568],{"class":399},[393,1380,1381],{"class":403}," -i.bak",[393,1383,1384],{"class":414}," 's\u002F^HTTP_LISTEN_ADDR=127\\.0\\.0\\.1:\u002FHTTP_LISTEN_ADDR=\u003Caddress>:\u002F'",[393,1386,1387],{"class":414}," '\u003Cenv_file>'",[393,1389,421],{"class":407},[393,1391,1048],{"class":399},[393,1393,1051],{"class":403},[393,1395,1396],{"class":414}," restart",[393,1398,1069],{"class":414},[393,1400,421],{"class":407},[393,1402,313],{"class":399},[393,1404,1405],{"class":414}," '^HTTP_LISTEN_ADDR='",[393,1407,1408],{"class":414}," '\u003Cenv_file>'\n",[201,1410,1152,1411,1413,1414,1416,1417,1419,1420,1423,1424,1426,1427,1429,1430,1433,1434,1437,1438,1440,1441,1443,1444,1446,1447,1450],{},[208,1412,764],{},", the plist holds a copy of ",[208,1415,556],{},": after the same ",[208,1418,568],{},",\nrun ",[208,1421,1422],{},"\"\u003Cbinary>\" server install --launchd --force",", then ",[208,1425,760],{}," from step\nS2 in place of the restart. For ",[208,1428,767],{},", the address lives in the compose\nfile instead: run ",[208,1431,1432],{},"sed -i.bak 's\u002F\"127\\.0\\.0\\.1:\u003Cport>:8080\"\u002F\"\u003Caddress>:\u003Cport>:8080\"\u002F' '\u003Cpath>' && docker compose -f '\u003Cpath>' up -d --force-recreate && grep -F ':8080\"' '\u003Cpath>'","\nin place of the whole command; a later ",[208,1435,1436],{},"server install --compose --force","\nputs it back on ",[208,1439,328],{},". With Compose, ",[208,1442,556],{}," keeps ",[208,1445,328],{},":\nreport the published address as ",[208,1448,1449],{},"listen"," in this outcome and in step S7.",[201,1452,1453,1455,1456,1458,1459,1461,1462,1179,1465,761,1467,1469,1470,1472,1473,1295],{},[217,1454,447],{}," without a change, nothing to check. After one, the last line\nshows ",[208,1457,283],{}," and the ",[208,1460,572],{}," command of step S3 against\n",[208,1463,1464],{},"http:\u002F\u002F\u003Caddress>:\u003Cport>\u002Fapi\u002Fv1\u002Fmeta",[208,1466,328],{},[208,1468,1313],{},") ends in\n",[208,1471,664],{},". Opening the firewall, setting up TLS and handing the key to others\ngo into step S7's ",[208,1474,1475],{},"human_todo",[201,1477,1478],{},[217,1479,465],{},[385,1481,1483],{"className":468,"code":1482,"language":227,"meta":389,"style":389},"{\"step\": \"S4\", \"status\": \"ok\", \"listen\": \"127.0.0.1:8090\", \"exposure\": \"this machine only\", \"tls\": \"none\", \"key_copy\": \"password manager\", \"shared_with\": []}\n",[208,1484,1485],{"__ignoreMap":389},[393,1486,1487,1489,1491,1493,1496,1498,1500,1502,1504,1506,1508,1510,1512,1514,1517,1519,1522,1524,1527,1529,1532,1534,1537,1539,1542,1544,1547],{"class":395,"line":396},[393,1488,476],{"class":407},[393,1490,479],{"class":403},[393,1492,482],{"class":407},[393,1494,1495],{"class":414},"\"S4\"",[393,1497,265],{"class":407},[393,1499,490],{"class":403},[393,1501,482],{"class":407},[393,1503,495],{"class":414},[393,1505,265],{"class":407},[393,1507,841],{"class":403},[393,1509,482],{"class":407},[393,1511,846],{"class":414},[393,1513,265],{"class":407},[393,1515,1516],{"class":403},"\"exposure\"",[393,1518,482],{"class":407},[393,1520,1521],{"class":414},"\"this machine only\"",[393,1523,265],{"class":407},[393,1525,1526],{"class":403},"\"tls\"",[393,1528,482],{"class":407},[393,1530,1531],{"class":414},"\"none\"",[393,1533,265],{"class":407},[393,1535,1536],{"class":403},"\"key_copy\"",[393,1538,482],{"class":407},[393,1540,1541],{"class":414},"\"password manager\"",[393,1543,265],{"class":407},[393,1545,1546],{"class":403},"\"shared_with\"",[393,1548,1549],{"class":407},": []}\n",[286,1551,1553],{"id":1552},"step-s5-wire-this-machines-client","Step S5: Wire this machine's client",[201,1555,1556,1558,1559,1219,1562,1565],{},[208,1557,275],{}," is ",[208,1560,1561],{},"http:\u002F\u002F127.0.0.1:\u003Cport>",[208,1563,1564],{},"http:\u002F\u002F\u003Caddress>:\u003Cport>"," when step\nS4 bound one interface's address. The client reads the key from the key file\non stdin, so nobody types it:",[385,1567,1569],{"className":387,"code":1568,"language":214,"meta":389,"style":389},"\"\u003Cbinary>\" doctor --init --url '\u003CURL>' --key-from-stdin \u003C '\u003Ckey_file>'\n",[208,1570,1571],{"__ignoreMap":389},[393,1572,1573,1575,1578,1580,1583,1586,1589,1592],{"class":395,"line":396},[393,1574,874],{"class":399},[393,1576,1577],{"class":414}," doctor",[393,1579,649],{"class":403},[393,1581,1582],{"class":403}," --url",[393,1584,1585],{"class":414}," '\u003CURL>'",[393,1587,1588],{"class":403}," --key-from-stdin",[393,1590,1591],{"class":435}," \u003C",[393,1593,1594],{"class":414}," '\u003Ckey_file>'\n",[201,1596,1597,1599,1600,1603,1604,1607,1608,1611,1612,1614,1615,1295],{},[217,1598,447],{}," the output is ",[208,1601,1602],{},"{\"status\":\"written\",\"path\":\"…\"}",", with\n",[208,1605,1606],{},"\"local_reports\""," when this machine's local database holds reports (client\nstep 2.3 handles them). A ",[208,1609,1610],{},"config already exists"," error is handled as in client step 2.2: ask the human whether to keep\nthe existing configuration or replace it with ",[208,1613,338],{}," after\n",[208,1616,1617],{},"--key-from-stdin",[201,1619,1620,1621,1624,1625,1628,1629,1635,1636,1640],{},"Then run client step 2.3 (or 2.4 or 2.5, as that step routes), client step\n3.1 and client step 3.2, each with its own outcome. Client step 3.2's\n",[208,1622,1623],{},"install-check"," row proves the whole path: client, server and database.\nThe OSS server does not offer transcript processing: the client reports\n",[208,1626,1627],{},"capture.state: unsupported"," and \"this server does not process sessions\".\nThis is an expected policy status, not a failed installation check.\nManual ",[205,1630,1632],{"href":1631},"\u002Fdocs\u002Freference\u002Fsessions#push",[208,1633,1634],{},"sessions push"," therefore sends no transcript\nto this stack, and the ",[205,1637,1639],{"href":1638},"\u002Fdocs\u002Freference\u002Fsessions#automatic-sweep","automatic sweep","\nis a no-op; both require a server whose organisation enables processing.\nThis also applies to Cursor's hook-indexed, storage-only transcripts:\ninstalling its hooks does not enable uploads to this OSS stack.",[201,1642,1643],{},[217,1644,465],{},[385,1646,1648],{"className":468,"code":1647,"language":227,"meta":389,"style":389},"{\"step\": \"S5\", \"status\": \"ok\", \"server\": \"\u003CURL>\", \"config\": \"\u002Fhome\u002Fuser\u002F.config\u002Fagentfeedback\u002Fconfig.toml\", \"install_check_id\": 1}\n",[208,1649,1650],{"__ignoreMap":389},[393,1651,1652,1654,1656,1658,1661,1663,1665,1667,1669,1671,1674,1676,1679,1681,1684,1686,1689,1691,1694,1696,1699],{"class":395,"line":396},[393,1653,476],{"class":407},[393,1655,479],{"class":403},[393,1657,482],{"class":407},[393,1659,1660],{"class":414},"\"S5\"",[393,1662,265],{"class":407},[393,1664,490],{"class":403},[393,1666,482],{"class":407},[393,1668,495],{"class":414},[393,1670,265],{"class":407},[393,1672,1673],{"class":403},"\"server\"",[393,1675,482],{"class":407},[393,1677,1678],{"class":414},"\"\u003CURL>\"",[393,1680,265],{"class":407},[393,1682,1683],{"class":403},"\"config\"",[393,1685,482],{"class":407},[393,1687,1688],{"class":414},"\"\u002Fhome\u002Fuser\u002F.config\u002Fagentfeedback\u002Fconfig.toml\"",[393,1690,265],{"class":407},[393,1692,1693],{"class":403},"\"install_check_id\"",[393,1695,482],{"class":407},[393,1697,1698],{"class":403},"1",[393,1700,537],{"class":407},[286,1702,1704],{"id":1703},"step-s6-the-triage-skill","Step S6: The triage skill",[201,1706,1707,1710,1711,1714,1715,1718],{},[208,1708,1709],{},"agentfeedback-triage"," processes the queue with the human, only when they\ninvoke it (",[208,1712,1713],{},"\u002Fagentfeedback-triage","). Client step 2.3 installed it with the\nrest of the wiring, unless the human declined and it ran with ",[208,1716,1717],{},"--no-triage",".\nUse client step 2.3's hook verification for each harness; Cline's plugin\nhooks apply to its SDK\u002FCLI, not its IDE extension.\nCheck it:",[385,1720,1722],{"className":387,"code":1721,"language":214,"meta":389,"style":389},"\"\u003Cbinary>\" install --list --json\n",[208,1723,1724],{"__ignoreMap":389},[393,1725,1726,1728,1730,1733],{"class":395,"line":396},[393,1727,874],{"class":399},[393,1729,880],{"class":414},[393,1731,1732],{"class":403}," --list",[393,1734,1735],{"class":403}," --json\n",[201,1737,1738,1740,1741,1744,1745,1614,1748,1750,1751,1754,1755,1758,1759,1762],{},[217,1739,447],{}," your harness shows ",[208,1742,1743],{},"\"triage\": \"wired\"",". It shows ",[208,1746,1747],{},"\"-\"",[208,1749,1717],{},", and after client step 2.4 or 2.5 when ",[208,1752,1753],{},"init"," did not run\n(the plugin or the ",[208,1756,1757],{},"skills"," CLI installs only the submission skill): report\nthe step as skipped with that reason. ",[208,1760,1761],{},"\"external\""," means a\ntriage skill installed another way was already there and was left as it is.",[201,1764,1765],{},[217,1766,465],{},[385,1768,1770],{"className":468,"code":1769,"language":227,"meta":389,"style":389},"{\"step\": \"S6\", \"status\": \"ok\", \"harness\": \"claude-code\", \"triage\": \"wired\"}\n",[208,1771,1772],{"__ignoreMap":389},[393,1773,1774,1776,1778,1780,1783,1785,1787,1789,1791,1793,1796,1798,1801,1803,1806,1808,1811],{"class":395,"line":396},[393,1775,476],{"class":407},[393,1777,479],{"class":403},[393,1779,482],{"class":407},[393,1781,1782],{"class":414},"\"S6\"",[393,1784,265],{"class":407},[393,1786,490],{"class":403},[393,1788,482],{"class":407},[393,1790,495],{"class":414},[393,1792,265],{"class":407},[393,1794,1795],{"class":403},"\"harness\"",[393,1797,482],{"class":407},[393,1799,1800],{"class":414},"\"claude-code\"",[393,1802,265],{"class":407},[393,1804,1805],{"class":403},"\"triage\"",[393,1807,482],{"class":407},[393,1809,1810],{"class":414},"\"wired\"",[393,1812,537],{"class":407},[286,1814,1816],{"id":1815},"step-s7-report","Step S7: Report",[201,1818,1819,1820,761,1822,408,1824,761,1827,1829],{},"Run client step 4 first. Then check the service once more with the status\ncommand of its form (",[208,1821,1165],{},[208,1823,767],{},[208,1825,1826],{},"launchctl print gui\u002F$(id -u)\u002Fdev.agentfeedback.serve",[208,1828,764],{},"):",[385,1831,1833],{"className":387,"code":1832,"language":214,"meta":389,"style":389},"systemctl --user status agentfeedback.service --no-pager\n",[208,1834,1835],{"__ignoreMap":389},[393,1836,1837,1839,1841,1844,1846],{"class":395,"line":396},[393,1838,1048],{"class":399},[393,1840,1051],{"class":403},[393,1842,1843],{"class":414}," status",[393,1845,1069],{"class":414},[393,1847,1848],{"class":403}," --no-pager\n",[201,1850,1851,1853,1854,1179,1857,280,1860,408,1862,1865,1866,761,1869,1183],{},[217,1852,447],{}," the output shows ",[208,1855,1856],{},"active (running)",[208,1858,1859],{},"state = running",[208,1861,764],{},[208,1863,1864],{},"Up"," or ",[208,1867,1868],{},"running",[208,1870,767],{},[201,1872,1873,1875,1876,254,1879,1882,1883,1885,1886,254,1888,761,1890,265,1892,254,1894,280,1896,265,1898,254,1900,761,1902,1183],{},[217,1874,465],{}," quote this to the human, with every earlier outcome above it.\n",[208,1877,1878],{},"status_command",[208,1880,1881],{},"backup_command"," come from step S2's ",[208,1884,271],{},"\n(",[208,1887,1202],{},[208,1889,760],{},[208,1891,757],{},[208,1893,1202],{},[208,1895,1235],{},[208,1897,764],{},[208,1899,1165],{},[208,1901,1235],{},[208,1903,767],{},[385,1905,1907],{"className":468,"code":1906,"language":227,"meta":389,"style":389},"{\"step\": \"S7\", \"status\": \"ok\", \"server\": {\"mode\": \"systemd\", \"listen\": \"127.0.0.1:8090\", \"env_file\": \"\u002Fhome\u002Fuser\u002F.config\u002Fagentfeedback\u002Fserver\u002Fserve.env\", \"key_file\": \"\u002Fhome\u002Fuser\u002F.config\u002Fagentfeedback\u002Fserver\u002Fapi-key\", \"database\": \"\u002Fhome\u002Fuser\u002F.local\u002Fshare\u002Fagentfeedback\u002Fagentfeedback.db\", \"status_command\": \"systemctl --user status agentfeedback.service\", \"backup_command\": \"set -a; . \u002Fhome\u002Fuser\u002F.config\u002Fagentfeedback\u002Fserver\u002Fserve.env; set +a; \u002Fhome\u002Fuser\u002F.local\u002Fbin\u002Fagentfeedback backup \u002Fhome\u002Fuser\u002F.local\u002Fshare\u002Fagentfeedback\u002Fagentfeedback-$(date -u +%Y%m%dT%H%M%SZ).db\"}, \"client\": {\"binary\": \"\u002Fhome\u002Fuser\u002F.local\u002Fbin\u002Fagentfeedback\", \"server\": \"http:\u002F\u002F127.0.0.1:8090\", \"harnesses\": [\"claude-code\"], \"install_check_id\": 1}, \"reachable_from\": \"coding agents with the binary or an MCP client that sends the key header (Claude Code, Codex, Cursor, OpenCode, omp, pi), on this machine and on every machine that reaches the listen address; Claude's chat apps (Claude.ai, Claude Desktop, Claude on mobile) through a custom connector with the key as a request header, once the server is reachable over public HTTPS (client step 2.8); ChatGPT not at all (OAuth only)\", \"human_todo\": [\"copy the key from the key file into your password manager\", \"restart the harness so it loads the skill\"]}\n",[208,1908,1909],{"__ignoreMap":389},[393,1910,1911,1913,1915,1917,1920,1922,1924,1926,1928,1930,1932,1935,1937,1939,1941,1943,1945,1947,1949,1951,1953,1955,1957,1959,1961,1963,1965,1967,1969,1971,1973,1975,1978,1980,1982,1984,1987,1989,1991,1994,1997,1999,2001,2003,2005,2007,2009,2011,2014,2016,2019,2021,2023,2026,2028,2030,2032,2034,2037,2039,2042,2044,2047,2049,2052,2054,2057],{"class":395,"line":396},[393,1912,476],{"class":407},[393,1914,479],{"class":403},[393,1916,482],{"class":407},[393,1918,1919],{"class":414},"\"S7\"",[393,1921,265],{"class":407},[393,1923,490],{"class":403},[393,1925,482],{"class":407},[393,1927,495],{"class":414},[393,1929,265],{"class":407},[393,1931,1673],{"class":403},[393,1933,1934],{"class":407},": {",[393,1936,967],{"class":403},[393,1938,482],{"class":407},[393,1940,972],{"class":414},[393,1942,265],{"class":407},[393,1944,841],{"class":403},[393,1946,482],{"class":407},[393,1948,846],{"class":414},[393,1950,265],{"class":407},[393,1952,821],{"class":403},[393,1954,482],{"class":407},[393,1956,826],{"class":414},[393,1958,265],{"class":407},[393,1960,811],{"class":403},[393,1962,482],{"class":407},[393,1964,816],{"class":414},[393,1966,265],{"class":407},[393,1968,831],{"class":403},[393,1970,482],{"class":407},[393,1972,836],{"class":414},[393,1974,265],{"class":407},[393,1976,1977],{"class":403},"\"status_command\"",[393,1979,482],{"class":407},[393,1981,1003],{"class":414},[393,1983,265],{"class":407},[393,1985,1986],{"class":403},"\"backup_command\"",[393,1988,482],{"class":407},[393,1990,1023],{"class":414},[393,1992,1993],{"class":407},"}, ",[393,1995,1996],{"class":403},"\"client\"",[393,1998,1934],{"class":407},[393,2000,519],{"class":403},[393,2002,482],{"class":407},[393,2004,524],{"class":414},[393,2006,265],{"class":407},[393,2008,1673],{"class":403},[393,2010,482],{"class":407},[393,2012,2013],{"class":414},"\"http:\u002F\u002F127.0.0.1:8090\"",[393,2015,265],{"class":407},[393,2017,2018],{"class":403},"\"harnesses\"",[393,2020,990],{"class":407},[393,2022,1800],{"class":414},[393,2024,2025],{"class":407},"], ",[393,2027,1693],{"class":403},[393,2029,482],{"class":407},[393,2031,1698],{"class":403},[393,2033,1993],{"class":407},[393,2035,2036],{"class":403},"\"reachable_from\"",[393,2038,482],{"class":407},[393,2040,2041],{"class":414},"\"coding agents with the binary or an MCP client that sends the key header (Claude Code, Codex, Cursor, OpenCode, omp, pi), on this machine and on every machine that reaches the listen address; Claude's chat apps (Claude.ai, Claude Desktop, Claude on mobile) through a custom connector with the key as a request header, once the server is reachable over public HTTPS (client step 2.8); ChatGPT not at all (OAuth only)\"",[393,2043,265],{"class":407},[393,2045,2046],{"class":403},"\"human_todo\"",[393,2048,990],{"class":407},[393,2050,2051],{"class":414},"\"copy the key from the key file into your password manager\"",[393,2053,265],{"class":407},[393,2055,2056],{"class":414},"\"restart the harness so it loads the skill\"",[393,2058,1031],{"class":407},[201,2060,2061,2062,2065,2066,2070,2071,2074],{},"The client's ",[208,2063,2064],{},"agentfeedback config"," menu changes only\n",[205,2067,2069],{"href":2068},"\u002Fdocs\u002Freference\u002Foperate#machine-settings","machine settings",", not this service's\nenvironment, destination credentials or organisation policy. Use\n",[208,2072,2073],{},"config show --json"," for inspection; destination\u002Fkey changes follow client\nstep 2.2.",[201,2076,2077,2079,2080,2082,2083,2085,2086,1295],{},[208,2078,1475],{}," holds what is left for the human, for example: copy the key\n(step S4); open the firewall, set up the reverse proxy or the tunnel (step\nS4); run the client playbook on each machine named in step S4 with ",[208,2081,275],{},"\nas the server; the client playbook's own items. Back up the database\nregularly with ",[208,2084,1881],{},". To remove the stack, see\n",[205,2087,2089,2090],{"href":2088},"\u002Fdocs\u002Freference\u002Foperate#a-service-from-server-install","the uninstall section of ",[208,2091,923],{},[2093,2094,2095],"style",{},"html pre.shiki code .snPdu, html code.shiki .snPdu{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sBjJW, html code.shiki .sBjJW{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sxrX7, html code.shiki .sxrX7{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#E1E4E8}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 .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);}html pre.shiki code .s3JiQ, html code.shiki .s3JiQ{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#DBEDFF}",{"title":389,"searchDepth":2097,"depth":2097,"links":2098},2,[2099,2100,2101,2102,2103,2104,2105,2106,2107],{"id":288,"depth":2097,"text":289},{"id":354,"depth":2097,"text":355},{"id":540,"depth":2097,"text":541},{"id":851,"depth":2097,"text":852},{"id":1034,"depth":2097,"text":1035},{"id":1287,"depth":2097,"text":1288},{"id":1552,"depth":2097,"text":1553},{"id":1703,"depth":2097,"text":1704},{"id":1815,"depth":2097,"text":1816},"You are an AI agent asked to install the AgentFeedback server and client on the machine you run on, and to verify reporting end to end.","md",{},{"title":190,"icon":193},{"title":196,"description":2108},null,"Fmj7TpZinq3XMWFfNLsLDzfX2VBJy1hnttkg9ol_h10",[2116,2113],{"title":185,"path":186,"stem":187,"description":2117,"icon":188,"children":-1},"You are an AI agent asked to install the AgentFeedback client and set it up for the harness you run in.",1794388868392]