[{"data":1,"prerenderedAt":836},["ShallowReactive",2],{"navigation":3,"external-navigation":214,"docs:\u002Feos\u002Fharbourmaster\u002Fdecisions\u002Fai-50-auth-and-fork-policy":443},[4,8,201],{"title":5,"path":6,"stem":7},"Documentation","\u002F","README",{"title":9,"path":10,"stem":11,"children":12},"EOS","\u002Feos","eos\u002FREADME",[13,44,121,181],{"title":14,"collapsed":15,"path":16,"stem":17,"children":18,"page":43},"Adrs",true,"\u002Feos\u002Fadrs","eos\u002Fadrs",[19,23,27,31,35,39],{"title":20,"path":21,"stem":22},"Use Turborepo for the EOS monorepo","\u002Feos\u002Fadrs\u002F0001-use-turborepo-for-eos","eos\u002Fadrs\u002F0001-use-turborepo-for-eos",{"title":24,"path":25,"stem":26},"Use Oxc for linting and formatting","\u002Feos\u002Fadrs\u002F0003-use-oxc-for-linting-and-formatting","eos\u002Fadrs\u002F0003-use-oxc-for-linting-and-formatting",{"title":28,"path":29,"stem":30},"Lint Markdown and validate links in CI","\u002Feos\u002Fadrs\u002F0004-lint-markdown-in-ci","eos\u002Fadrs\u002F0004-lint-markdown-in-ci",{"title":32,"path":33,"stem":34},"Use Lefthook for repository-managed Git hooks","\u002Feos\u002Fadrs\u002F0005-use-lefthook-for-repository-git-hooks","eos\u002Fadrs\u002F0005-use-lefthook-for-repository-git-hooks",{"title":36,"path":37,"stem":38},"Use Commitlint's conventional configuration","\u002Feos\u002Fadrs\u002F0006-use-commitlint-conventional-configuration","eos\u002Fadrs\u002F0006-use-commitlint-conventional-configuration",{"title":40,"path":41,"stem":42},"Use Nx for EOS task execution","\u002Feos\u002Fadrs\u002F0007-use-nx-for-eos","eos\u002Fadrs\u002F0007-use-nx-for-eos",false,{"title":45,"path":46,"stem":47,"children":48},"Harbourmaster","\u002Feos\u002Fharbourmaster","eos\u002Fharbourmaster\u002FREADME",[49,58,71,96],{"title":50,"path":51,"stem":52,"children":53,"page":43},"Decisions","\u002Feos\u002Fharbourmaster\u002Fdecisions","eos\u002Fharbourmaster\u002Fdecisions",[54],{"title":55,"path":56,"stem":57},"AI-50: GitHub auth and fork pull request policy","\u002Feos\u002Fharbourmaster\u002Fdecisions\u002Fai-50-auth-and-fork-policy","eos\u002Fharbourmaster\u002Fdecisions\u002Fai-50-auth-and-fork-policy",{"title":59,"path":60,"stem":61,"children":62,"page":43},"Explanation","\u002Feos\u002Fharbourmaster\u002Fexplanation","eos\u002Fharbourmaster\u002Fexplanation",[63,67],{"title":64,"path":65,"stem":66},"The Harbourmaster review pipeline","\u002Feos\u002Fharbourmaster\u002Fexplanation\u002Freview-pipeline","eos\u002Fharbourmaster\u002Fexplanation\u002Freview-pipeline",{"title":68,"path":69,"stem":70},"The Harbourmaster shared-action trust boundary","\u002Feos\u002Fharbourmaster\u002Fexplanation\u002Fshared-action-trust-boundary","eos\u002Fharbourmaster\u002Fexplanation\u002Fshared-action-trust-boundary",{"title":72,"path":73,"stem":74,"children":75,"page":43},"How To","\u002Feos\u002Fharbourmaster\u002Fhow-to","eos\u002Fharbourmaster\u002Fhow-to",[76,80,84,88,92],{"title":77,"path":78,"stem":79},"How to add Harbourmaster reviews to a repository","\u002Feos\u002Fharbourmaster\u002Fhow-to\u002Fadd-harbourmaster-to-a-repository","eos\u002Fharbourmaster\u002Fhow-to\u002Fadd-harbourmaster-to-a-repository",{"title":81,"path":82,"stem":83},"How to build a pilot dashboard","\u002Feos\u002Fharbourmaster\u002Fhow-to\u002Fbuild-pilot-dashboard","eos\u002Fharbourmaster\u002Fhow-to\u002Fbuild-pilot-dashboard",{"title":85,"path":86,"stem":87},"How to configure model routing","\u002Feos\u002Fharbourmaster\u002Fhow-to\u002Fconfigure-model-routing","eos\u002Fharbourmaster\u002Fhow-to\u002Fconfigure-model-routing",{"title":89,"path":90,"stem":91},"How to request a Harbourmaster review","\u002Feos\u002Fharbourmaster\u002Fhow-to\u002Frequest-a-review","eos\u002Fharbourmaster\u002Fhow-to\u002Frequest-a-review",{"title":93,"path":94,"stem":95},"How to diagnose a Harbourmaster review failure","\u002Feos\u002Fharbourmaster\u002Fhow-to\u002Ftroubleshoot-a-review","eos\u002Fharbourmaster\u002Fhow-to\u002Ftroubleshoot-a-review",{"title":97,"path":98,"stem":99,"children":100,"page":43},"Reference","\u002Feos\u002Fharbourmaster\u002Freference","eos\u002Fharbourmaster\u002Freference",[101,105,109,113,117],{"title":102,"path":103,"stem":104},"Harbourmaster command-line interface","\u002Feos\u002Fharbourmaster\u002Freference\u002Fcli","eos\u002Fharbourmaster\u002Freference\u002Fcli",{"title":106,"path":107,"stem":108},"Harbourmaster configuration","\u002Feos\u002Fharbourmaster\u002Freference\u002Fconfiguration","eos\u002Fharbourmaster\u002Freference\u002Fconfiguration",{"title":110,"path":111,"stem":112},"Harbourmaster GitHub Action","\u002Feos\u002Fharbourmaster\u002Freference\u002Fgithub-action","eos\u002Fharbourmaster\u002Freference\u002Fgithub-action",{"title":114,"path":115,"stem":116},"Harbourmaster review behavior","\u002Feos\u002Fharbourmaster\u002Freference\u002Freview-behavior","eos\u002Fharbourmaster\u002Freference\u002Freview-behavior",{"title":118,"path":119,"stem":120},"Harbourmaster telemetry","\u002Feos\u002Fharbourmaster\u002Freference\u002Ftelemetry","eos\u002Fharbourmaster\u002Freference\u002Ftelemetry",{"title":72,"path":122,"stem":123,"children":124,"page":43},"\u002Feos\u002Fhow-to","eos\u002Fhow-to",[125,129,133,137,141,145,149,153,157,161,165,169,173,177],{"title":126,"path":127,"stem":128},"How to add an external documentation source","\u002Feos\u002Fhow-to\u002Fadd-external-documentation-source","eos\u002Fhow-to\u002Fadd-external-documentation-source",{"title":130,"path":131,"stem":132},"How to connect SDLC integrations","\u002Feos\u002Fhow-to\u002Fconnect-sdlc-integrations","eos\u002Fhow-to\u002Fconnect-sdlc-integrations",{"title":134,"path":135,"stem":136},"How to consume the EOS plugin marketplace","\u002Feos\u002Fhow-to\u002Fconsume-eos-marketplace","eos\u002Fhow-to\u002Fconsume-eos-marketplace",{"title":138,"path":139,"stem":140},"How to create a spike ticket","\u002Feos\u002Fhow-to\u002Fcreate-spike-ticket","eos\u002Fhow-to\u002Fcreate-spike-ticket",{"title":142,"path":143,"stem":144},"How to finalise a repository change","\u002Feos\u002Fhow-to\u002Ffinalise-change","eos\u002Fhow-to\u002Ffinalise-change",{"title":146,"path":147,"stem":148},"How to install the EOS Docs MCP server","\u002Feos\u002Fhow-to\u002Finstall-eos-docs-mcp","eos\u002Fhow-to\u002Finstall-eos-docs-mcp",{"title":150,"path":151,"stem":152},"How to resolve a spike ticket","\u002Feos\u002Fhow-to\u002Fresolve-spike-ticket","eos\u002Fhow-to\u002Fresolve-spike-ticket",{"title":154,"path":155,"stem":156},"How to run Git hook checks","\u002Feos\u002Fhow-to\u002Frun-git-hook-checks","eos\u002Fhow-to\u002Frun-git-hook-checks",{"title":158,"path":159,"stem":160},"How to use the AI-enabled SDLC","\u002Feos\u002Fhow-to\u002Fuse-ai-enabled-sdlc","eos\u002Fhow-to\u002Fuse-ai-enabled-sdlc",{"title":162,"path":163,"stem":164},"Use the Aikido plugin","\u002Feos\u002Fhow-to\u002Fuse-aikido-plugin","eos\u002Fhow-to\u002Fuse-aikido-plugin",{"title":166,"path":167,"stem":168},"How to use Compass","\u002Feos\u002Fhow-to\u002Fuse-compass","eos\u002Fhow-to\u002Fuse-compass",{"title":170,"path":171,"stem":172},"How to use Fallow","\u002Feos\u002Fhow-to\u002Fuse-fallow","eos\u002Fhow-to\u002Fuse-fallow",{"title":174,"path":175,"stem":176},"How to use incremental mutation tests","\u002Feos\u002Fhow-to\u002Fuse-incremental-mutation-tests","eos\u002Fhow-to\u002Fuse-incremental-mutation-tests",{"title":178,"path":179,"stem":180},"How to use Scout","\u002Feos\u002Fhow-to\u002Fuse-scout","eos\u002Fhow-to\u002Fuse-scout",{"title":97,"path":182,"stem":183,"children":184,"page":43},"\u002Feos\u002Freference","eos\u002Freference",[185,189,193,197],{"title":186,"path":187,"stem":188},"Compass CLI","\u002Feos\u002Freference\u002Fcompass-cli","eos\u002Freference\u002Fcompass-cli",{"title":190,"path":191,"stem":192},"EOS marketplace skills","\u002Feos\u002Freference\u002Fmarketplace-skills","eos\u002Freference\u002Fmarketplace-skills",{"title":194,"path":195,"stem":196},"Nx task execution and cache","\u002Feos\u002Freference\u002Fnx-task-execution","eos\u002Freference\u002Fnx-task-execution",{"title":198,"path":199,"stem":200},"Scout CLI","\u002Feos\u002Freference\u002Fscout-cli","eos\u002Freference\u002Fscout-cli",{"title":202,"path":203,"stem":204,"children":205},"Product engineering","\u002Fproduct-engineering","product-engineering\u002FREADME",[206],{"title":14,"collapsed":15,"path":207,"stem":208,"children":209,"page":43},"\u002Fproduct-engineering\u002Fadrs","product-engineering\u002Fadrs",[210],{"title":211,"path":212,"stem":213},"Codify Engineering Standards as Skills","\u002Fproduct-engineering\u002Fadrs\u002F0002-codify-engineering-standards-as-skills","product-engineering\u002Fadrs\u002F0002-codify-engineering-standards-as-skills",[215,268],{"nav":216,"source":265},[217],{"title":218,"path":219,"stem":220,"children":221},"Ember","\u002Fember","ember",[222,225,257,261],{"title":223,"path":219,"stem":224},"StoreFront Documentation","ember\u002Findex",{"title":14,"path":226,"stem":227,"children":228,"page":43},"\u002Fember\u002Fadrs","ember\u002Fadrs",[229,233,237,241,245,249,253],{"title":230,"path":231,"stem":232},"Add Infection as a non-blocking mutation testing tool for Ember","\u002Fember\u002Fadrs\u002F0001-infection-mutation-testing","ember\u002Fadrs\u002F0001-infection-mutation-testing",{"title":234,"path":235,"stem":236},"Process DELETE scheduled changes before CREATE_UPDATE at the same instant","\u002Fember\u002Fadrs\u002F0002-scheduled-change-processing-order","ember\u002Fadrs\u002F0002-scheduled-change-processing-order",{"title":238,"path":239,"stem":240},"Standard rate scheduling is permanent until overridden","\u002Fember\u002Fadrs\u002F0003-standard-rate-scheduling-is-permanent","ember\u002Fadrs\u002F0003-standard-rate-scheduling-is-permanent",{"title":242,"path":243,"stem":244},"Promotions require an existing standard rate","\u002Fember\u002Fadrs\u002F0004-promotions-require-existing-standard-rate","ember\u002Fadrs\u002F0004-promotions-require-existing-standard-rate",{"title":246,"path":247,"stem":248},"UTC datetime contract between Storefront and Hub","\u002Fember\u002Fadrs\u002F0005-utc-datetime-contract-between-storefront-and-hub","ember\u002Fadrs\u002F0005-utc-datetime-contract-between-storefront-and-hub",{"title":250,"path":251,"stem":252},"Elapsed unprocessed scheduled changes do not block rate changes","\u002Fember\u002Fadrs\u002F0006-stale-scheduler-rows-do-not-block-rate-changes","ember\u002Fadrs\u002F0006-stale-scheduler-rows-do-not-block-rate-changes",{"title":254,"path":255,"stem":256},"ADR-0007: Delete ConfigureTenantAuth routing command once OIDC setup migrates to Hub","\u002Fember\u002Fadrs\u002F0007-delete-configure-tenant-auth-routing-command","ember\u002Fadrs\u002F0007-delete-configure-tenant-auth-routing-command",{"title":258,"path":259,"stem":260},"Domain Overview","\u002Fember\u002Fdomain_overview","ember\u002Fdomain_overview",{"title":262,"path":263,"stem":264},"Main Flows","\u002Fember\u002Fkey_flows","ember\u002Fkey_flows",{"collectionName":266,"label":267,"prefix":220},"external_ember","StoreFront (Ember)",{"nav":269,"source":441},[270],{"title":271,"path":272,"stem":273,"children":274},"Core","\u002Fcore","core",[275,278,306,310,332,336,346,363,420,424],{"title":276,"path":272,"stem":277},"Documentation Index","core\u002Findex",{"title":14,"path":279,"stem":280,"children":281,"page":43},"\u002Fcore\u002Fadrs","core\u002Fadrs",[282,286,290,294,298,302],{"title":283,"path":284,"stem":285},"ADR-XXXX: Short, descriptive title","\u002Fcore\u002Fadrs\u002F0000-template","core\u002Fadrs\u002F0000-template",{"title":287,"path":288,"stem":289},"ADR-1: Promotions endpoint","\u002Fcore\u002Fadrs\u002F0001-add-promotions-endpoint","core\u002Fadrs\u002F0001-add-promotions-endpoint",{"title":291,"path":292,"stem":293},"ADR-2: EOM partner report job dispatch","\u002Fcore\u002Fadrs\u002F0002-eom-report-job-dispatch","core\u002Fadrs\u002F0002-eom-report-job-dispatch",{"title":295,"path":296,"stem":297},"ADR-3: Replace PB fee waive flag with a Zero scheme override","\u002Fcore\u002Fadrs\u002F0003-replace-pb-fee-waive-with-zero-scheme","core\u002Fadrs\u002F0003-replace-pb-fee-waive-with-zero-scheme",{"title":299,"path":300,"stem":301},"ADR-4: No processor Digital Top-up capability gate in Reloadable Commercials","\u002Fcore\u002Fadrs\u002F0004-no-processor-top-up-capability-gate","core\u002Fadrs\u002F0004-no-processor-top-up-capability-gate",{"title":303,"path":304,"stem":305},"ADR-5: Sparse polymorphic sale fee override reason stamp","\u002Fcore\u002Fadrs\u002F0005-sale-fee-override-reason-stamp","core\u002Fadrs\u002F0005-sale-fee-override-reason-stamp",{"title":307,"path":308,"stem":309},"Agent Workflow","\u002Fcore\u002Fai-workflow","core\u002Fai-workflow",{"title":311,"path":312,"stem":313,"children":314},"Backend Guide","\u002Fcore\u002Fbackend","core\u002Fbackend\u002Findex",[315,316,320,324,328],{"title":311,"path":312,"stem":313},{"title":317,"path":318,"stem":319},"Backend AI Tooling","\u002Fcore\u002Fbackend\u002Fai-tooling","core\u002Fbackend\u002Fai-tooling",{"title":321,"path":322,"stem":323},"Backend Linting and Formatting","\u002Fcore\u002Fbackend\u002Flinting-and-formatting","core\u002Fbackend\u002Flinting-and-formatting",{"title":325,"path":326,"stem":327},"Backend Setup","\u002Fcore\u002Fbackend\u002Fsetup","core\u002Fbackend\u002Fsetup",{"title":329,"path":330,"stem":331},"Backend Testing","\u002Fcore\u002Fbackend\u002Ftesting","core\u002Fbackend\u002Ftesting",{"title":333,"path":334,"stem":335},"Documentation Health","\u002Fcore\u002Fdoc-health","core\u002Fdoc-health",{"title":337,"path":338,"stem":339,"children":340},"Frontend Guide","\u002Fcore\u002Ffrontend","core\u002Ffrontend\u002Findex",[341,342],{"title":337,"path":338,"stem":339},{"title":343,"path":344,"stem":345},"Frontend Development","\u002Fcore\u002Ffrontend\u002Fdevelopment","core\u002Ffrontend\u002Fdevelopment",{"title":347,"path":348,"stem":349,"children":350,"page":43},"Modules","\u002Fcore\u002Fmodules","core\u002Fmodules",[351,355],{"title":352,"path":353,"stem":354},"Connect API","\u002Fcore\u002Fmodules\u002Fconnect-api","core\u002Fmodules\u002Fconnect-api",{"title":356,"path":357,"stem":358,"children":359,"page":43},"Secure Links","\u002Fcore\u002Fmodules\u002Fsecure-links","core\u002Fmodules\u002Fsecure-links",[360],{"title":356,"path":361,"stem":362},"\u002Fcore\u002Fmodules\u002Fsecure-links\u002Fsecure-links","core\u002Fmodules\u002Fsecure-links\u002Fsecure-links",{"title":364,"path":365,"stem":366,"children":367,"page":43},"Processors","\u002Fcore\u002Fprocessors","core\u002Fprocessors",[368,372,376,380,384,388,392,396,400,404,408,412,416],{"title":369,"path":370,"stem":371},"Amazon Processor and API","\u002Fcore\u002Fprocessors\u002Famazon","core\u002Fprocessors\u002Famazon",{"title":373,"path":374,"stem":375},"Amilon Processor and API","\u002Fcore\u002Fprocessors\u002Familon","core\u002Fprocessors\u002Familon",{"title":377,"path":378,"stem":379},"Cadooz Processor and API","\u002Fcore\u002Fprocessors\u002Fcadooz","core\u002Fprocessors\u002Fcadooz",{"title":381,"path":382,"stem":383},"Choice Digital Processor and API","\u002Fcore\u002Fprocessors\u002Fchoice-digital","core\u002Fprocessors\u002Fchoice-digital",{"title":385,"path":386,"stem":387},"Diggecard processor reference","\u002Fcore\u002Fprocessors\u002Fdiggecard","core\u002Fprocessors\u002Fdiggecard",{"title":389,"path":390,"stem":391},"ePay Processor and API","\u002Fcore\u002Fprocessors\u002Fepay","core\u002Fprocessors\u002Fepay",{"title":393,"path":394,"stem":395},"GoGift v2 Processor and API","\u002Fcore\u002Fprocessors\u002Fgo-gift-v2","core\u002Fprocessors\u002Fgo-gift-v2",{"title":397,"path":398,"stem":399},"InComm Processor and API","\u002Fcore\u002Fprocessors\u002Fincomm","core\u002Fprocessors\u002Fincomm",{"title":401,"path":402,"stem":403},"Ogloba Processor and API","\u002Fcore\u002Fprocessors\u002Fogloba","core\u002Fprocessors\u002Fogloba",{"title":405,"path":406,"stem":407},"SVSECard Processor and API","\u002Fcore\u002Fprocessors\u002Fsvs-ecard","core\u002Fprocessors\u002Fsvs-ecard",{"title":409,"path":410,"stem":411},"Vananam Processor and API","\u002Fcore\u002Fprocessors\u002Fvananam","core\u002Fprocessors\u002Fvananam",{"title":413,"path":414,"stem":415},"Vouchers Depot processor reference","\u002Fcore\u002Fprocessors\u002Fvouchers-depot","core\u002Fprocessors\u002Fvouchers-depot",{"title":417,"path":418,"stem":419},"You Got a Gift Processor and API","\u002Fcore\u002Fprocessors\u002Fyou-got-a-gift","core\u002Fprocessors\u002Fyou-got-a-gift",{"title":421,"path":422,"stem":423},"Development Quickstart","\u002Fcore\u002Fsetup","core\u002Fsetup",{"title":425,"path":426,"stem":427,"children":428,"page":43},"Workflows","\u002Fcore\u002Fworkflows","core\u002Fworkflows",[429,433,437],{"title":430,"path":431,"stem":432},"Hub Endpoint Workflow","\u002Fcore\u002Fworkflows\u002Fhub-endpoints","core\u002Fworkflows\u002Fhub-endpoints",{"title":434,"path":435,"stem":436},"OpenAPI Tooling","\u002Fcore\u002Fworkflows\u002Fopenapi-tooling","core\u002Fworkflows\u002Fopenapi-tooling",{"title":438,"path":439,"stem":440},"Processor Integration Workflow","\u002Fcore\u002Fworkflows\u002Fprocessors","core\u002Fworkflows\u002Fprocessors",{"collectionName":442,"label":271,"prefix":273},"external_core",{"page":444,"surround":833},{"id":445,"title":55,"body":446,"config":828,"description":567,"extension":829,"meta":830,"navigation":15,"path":56,"seo":831,"stem":57,"__hash__":832},"docs\u002Feos\u002Fharbourmaster\u002Fdecisions\u002Fai-50-auth-and-fork-policy.md",{"type":447,"value":448,"toc":818},"minimark",[449,454,458,471,474,492,496,503,506,513,517,520,523,526,554,558,561,617,635,638,649,661,664,668,671,792,798,807,811,814],[450,451,453],"h2",{"id":452},"status","Status",[455,456,457],"p",{},"Accepted for the pilot slice.",[455,459,460,461,465,466,470],{},"This record keeps the original decision. Live operator rules are in\n",[462,463,77],"a",{"href":464},"..\u002Fhow-to\u002Fadd-harbourmaster-to-a-repository","\nand the ",[462,467,469],{"href":468},"..\u002Freference\u002Fgithub-action","GitHub Action reference",".",[455,472,473],{},"Implementation after the pilot slice changed these parts:",[475,476,477,481,484],"ul",{},[478,479,480],"li",{},"The workflow skips fork pull requests before checkout. They do not run a\nread-only review.",[478,482,483],{},"Dependabot has no extra skip rule. A same-repository Dependabot pull request\ncan start a review.",[478,485,486,487,491],{},"The trusted OpenCode ",[488,489,490],"code",{},"publish_review"," plugin publishes the advisory review.\nThe TypeScript runner verifies the marked review and the private receipt.",[450,493,495],{"id":494},"decision","Decision",[455,497,498,499,502],{},"Harbourmaster will run the pilot from GitHub Actions using either the workflow\n",[488,500,501],{},"GITHUB_TOKEN"," for same-repository pull requests or a GitHub App installation\ntoken for org-wide rollout. All GitHub reads and writes must stay behind the\nOctokit provider layer. Reviewer runtime code receives only provider-neutral\npull request context and review results.",[455,504,505],{},"The pilot starts in comment-only mode. Harbourmaster publishes one pull request\nreview containing the summary and any mappable inline findings. It must not\napprove, request changes, merge, label, close, or otherwise mutate repository\nstate during this slice.",[455,507,508,509,512],{},"Consumer repositories run ",[488,510,511],{},"TilloTech\u002Feos\u002Fapps\u002Fharbourmaster@main",", using the\nlatest Harbourmaster version merged to EOS. EOS self-reviews are an explicit\nexception: same-repository, non-draft EOS pull requests run the local action\nfrom the exact pull request head so Harbourmaster changes can be tested before\nmerge. This invariant does not apply to consumer repositories.",[450,514,516],{"id":515},"fork-and-dependabot-behavior","Fork and Dependabot behavior",[455,518,519],{},"Fork pull requests are skipped by the supported workflow before checkout. The\nrunner also skips fork pull requests by policy. They do not run read-only\ncontext construction or OpenCode review execution.",[455,521,522],{},"Dependabot pull requests from the same repository are not forks. They have no\nextra skip rule and can start a review unless a separate workflow guard excludes\nthem.",[455,524,525],{},"The safe boundary is:",[475,527,528,531,538,541,548],{},[478,529,530],{},"The supported workflow skips fork and draft pull requests before checkout,\ndependency installation, OIDC, or action execution.",[478,532,533,534,537],{},"Do not run ",[488,535,536],{},"pull_request_target"," against untrusted head code.",[478,539,540],{},"Do not let OpenCode call GitHub APIs directly.",[478,542,543,544,547],{},"Load Harbourmaster agents and plugins only from the trusted bundled runtime\nconfiguration. Repository-owned ",[488,545,546],{},".opencode"," files are review context, not\nexecutable reviewer configuration.",[478,549,550,551,553],{},"The trusted ",[488,552,490],{}," plugin publishes the advisory review after the\nrunner validates it.",[450,555,557],{"id":556},"required-github-permissions","Required GitHub permissions",[455,559,560],{},"Same-repository pilot workflows should request the minimum permissions needed\nfor the enabled phase:",[562,563,568],"pre",{"className":564,"code":565,"language":566,"meta":567,"style":567},"language-yaml shiki shiki-themes github-dark github-light","permissions:\n  contents: read\n  pull-requests: write\n  issues: write\n","yaml","",[488,569,570,583,596,607],{"__ignoreMap":567},[571,572,575,579],"span",{"class":573,"line":574},"line",1,[571,576,578],{"class":577},"sZkSk","permissions",[571,580,582],{"class":581},"sQ3_J",":\n",[571,584,586,589,592],{"class":573,"line":585},2,[571,587,588],{"class":577},"  contents",[571,590,591],{"class":581},": ",[571,593,595],{"class":594},"sg6BJ","read\n",[571,597,599,602,604],{"class":573,"line":598},3,[571,600,601],{"class":577},"  pull-requests",[571,603,591],{"class":581},[571,605,606],{"class":594},"write\n",[571,608,610,613,615],{"class":573,"line":609},4,[571,611,612],{"class":577},"  issues",[571,614,591],{"class":581},[571,616,606],{"class":594},[455,618,619,622,623,626,627,630,631,634],{},[488,620,621],{},"contents: read"," is required to load repository context. ",[488,624,625],{},"pull-requests: write","\nlets the review job apply ",[488,628,629],{},"harbourmaster-review"," and create PR reviews.\n",[488,632,633],{},"issues: write"," lets the job create the repository label when it is missing and\nsupports issue comment reads for duplicate suppression. Harbourmaster itself\nmust not add or remove labels; only the workflow label step does.",[455,636,637],{},"GitHub App installations need the same repository permissions:",[475,639,640,643,646],{},[478,641,642],{},"Contents: read",[478,644,645],{},"Pull requests: read and write",[478,647,648],{},"Issues: read",[455,650,651,652,654,655,657,658,660],{},"The supported workflow still uses ",[488,653,501],{}," with ",[488,656,633],{}," to create\nthe ",[488,659,629],{}," label. That label step does not use the App token.",[455,662,663],{},"Future checks or status reporting must add only the specific permission needed\nby that feature.",[450,665,667],{"id":666},"opencode-runtime-policy","OpenCode runtime policy",[455,669,670],{},"OpenCode is the reviewer runtime, not the GitHub publisher.",[475,672,673,676,679,682,689,703,711,718,740,743,746,758,761,764,767,770,773,786,789],{},[478,674,675],{},"Credentials are passed through explicitly named environment variables owned by\nthe runtime boundary.",[478,677,678],{},"CI uses Harbourmaster's bundled OpenCode configuration and never executes\nagents or plugins from the repository being reviewed.",[478,680,681],{},"The reviewed repository is passed as an explicit absolute workspace root.",[478,683,684,685,688],{},"The canonical workspace path must remain inside a separately supplied trusted\nboundary such as ",[488,686,687],{},"GITHUB_WORKSPACE","; symlink escapes are rejected.",[478,690,691,692,695,696,699,700,470],{},"OpenCode starts in an isolated diff directory. Before it starts, the trusted\nrunner writes ",[488,693,694],{},"review-index.json",", ",[488,697,698],{},"shared-pr-context.txt",", and\n",[488,701,702],{},"review-discussion.txt",[478,704,705,707,708,470],{},[488,706,694],{}," records the repository root, exact base and head, changed\npaths, statuses, rename paths, patch paths, and per-hunk base, head, and\npatch-line ranges. A missing patch path is ",[488,709,710],{},"null",[478,712,713,714,717],{},"The editor keeps the required publication and lifecycle context inline. It\ninvokes ",[488,715,716],{},"spawn_reviewers"," directly and cannot write or copy review context.",[478,719,720,721,695,724,727,728,731,732,735,736,739],{},"Specialists and the verifier may use only the read-only tools ",[488,722,723],{},"read",[488,725,726],{},"glob",",\n",[488,729,730],{},"grep",", and ",[488,733,734],{},"list",". A session-bound ",[488,737,738],{},"read_more"," tool can continue a truncated\nrepository result.",[478,741,742],{},"The code-quality reviewer receives the canonical checkout root in its prompt\nand can inspect that checkout alongside the staged diff material. Other\nspecialists and the verifier can inspect only the staged diff material.",[478,744,745],{},"The pinned OpenCode runtime enforces external-directory permissions. A per-run\noverride grants the code-quality reviewer access to the canonical checkout\nroot. All other external-directory access remains denied.",[478,747,748,749,695,751,695,753,731,755,757],{},"A trusted hook canonicalizes paths for ",[488,750,723],{},[488,752,726],{},[488,754,730],{},[488,756,734],{}," and\nrejects symlink escapes before those tools access files.",[478,759,760],{},"Shell, mutation, network, and nested-agent access remain denied.",[478,762,763],{},"Harbourmaster contract tests verify these permissions. OpenCode upgrades must\npreserve this permission contract before the pin moves.",[478,765,766],{},"Repository files and instructions are untrusted review context and cannot\noverride Harbourmaster safety, tool, scope, validation, or publication rules.",[478,768,769],{},"Findings remain limited to behavior introduced by the pull request and must be\nanchored to changed lines even when repository context supplies evidence.",[478,771,772],{},"Reviewers must start with the index, inspect every relevant changed patch,\nsearch callers, read source ranges, and read tests when the role permits those\nreads. Missing or truncated results do not prove that no finding exists.",[478,774,775,776,779,780,783,784,470],{},"The SDK server may be ",[488,777,778],{},"owned-per-run"," for CI isolation or ",[488,781,782],{},"shared-external","\nfor local development. CI should prefer ",[488,785,778],{},[478,787,788],{},"Sessions are scoped to one PR review run and may be shared only across\nreviewer agents within that run.",[478,790,791],{},"OpenCode output must be validated into the provider-neutral review result\nschema before any Octokit publishing step.",[450,793,795,797],{"id":794},"pull_request_target-policy",[488,796,536],{}," policy",[455,799,800,801,803,804,806],{},"Harbourmaster must not use ",[488,802,536],{}," for executing untrusted pull\nrequest code. A future trusted maintainer workflow may use ",[488,805,536],{},"\nonly to publish previously generated, validated artifacts from a trusted source,\nand only if it avoids checking out or executing the untrusted head ref.",[450,808,810],{"id":809},"consequences","Consequences",[455,812,813],{},"This keeps the pilot safe and reviewable: GitHub permissions are narrow,\npublishing remains centralized in Octokit, and OpenCode can be swapped or tested\nbehind the runtime contract without leaking provider-specific fields into\nreviewer logic.",[815,816,817],"style",{},"html pre.shiki code .sZkSk, html code.shiki .sZkSk{--shiki-dark:#85E89D;--shiki-default:#22863A}html pre.shiki code .sQ3_J, html code.shiki .sQ3_J{--shiki-dark:#E1E4E8;--shiki-default:#24292E}html pre.shiki code .sg6BJ, html code.shiki .sg6BJ{--shiki-dark:#9ECBFF;--shiki-default:#032F62}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 .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);}",{"title":567,"searchDepth":598,"depth":598,"links":819},[820,821,822,823,824,825,827],{"id":452,"depth":585,"text":453},{"id":494,"depth":585,"text":495},{"id":515,"depth":585,"text":516},{"id":556,"depth":585,"text":557},{"id":666,"depth":585,"text":667},{"id":794,"depth":585,"text":826},"pull_request_target policy",{"id":809,"depth":585,"text":810},{},"md",{},{"title":55,"description":567},"oJVthgwowHXTjAq6LDTVPovd-nUjQRPQGI25IRZY7w8",[834,835],{"title":45,"path":46,"stem":47,"children":-1},{"title":64,"path":65,"stem":66,"children":-1},1789777547833]