[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M71CGPPVJR873V6Q4PZY6NH9":3,"skill-same:01M71CGPPVJR873V6Q4PZY6NH9":65},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":38,"linkOnly":39,"markdownContent":40,"markdownBody":41,"frontMatter":42,"refName":43,"commitSha":44,"skillDirectory":45,"forksCount":46,"repositoryHtmlUrl":47,"repositoryHomepageUrl":6,"ownerHtmlUrl":48,"ownerBlogUrl":49,"ownerDescription":6,"updatedAt":50,"install":51,"resources":64},"01M71CGPPVJR873V6Q4PZY6NH9","cogbox-git",null,"Clone, fetch or push repositories, call the git host API (merge requests, issues, pipelines) through host-held credentials, find granted repos, decode denials and know what to ask the owner for.","illustris\u002Fcogbox","illustris","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F3948275?v=4","01M71CGEWJV83CKXRREGQKXXQH","01M71CGEXJJK2726RZ2EJDC1PM",3,"MIT","https:\u002F\u002Fgithub.com\u002Fillustris\u002Fcogbox\u002Fblob\u002Fmaster\u002Fskills\u002Fcogbox-git\u002FSKILL.md",[],[18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"git","cogbox git","clone","pipelines","merge requests","repos","find","merge","requests","decode","credentials","api","ask","repositories","host","call","issues","for","push","fetch","2026-11-10 10:12:30",false,"---\nname: cogbox-git\ndescription: Clone, fetch or push repositories, call the git host API (merge requests, issues, pipelines) through host-held credentials, find granted repos, decode denials and know what to ask the owner for.\n---\n\nRead `\u002Frun\u002Fcogbox\u002Fenvironment.json` as `cogbox-environment` describes. `cogworx`: everything below applies except the last section. `local`: only the last section applies. `unknown`, missing or malformed: ask whether the user runs local cogbox or a managed cogworx sandbox before giving git-access instructions.\n\nIf an installed plugin ships a skill for a particular git host (the `cogbox-plugins` skill lists them with their plugin), use it for that host's specifics; the credential rules in this skill still apply to every host.\n\n## Remotes and credentials\n\nIn cogworx, repository access comes from grants the sandbox's owner makes on its Git access tab, for git hosts the operator connected to cogworx (GitLab API hosts). The host side adds the owner's credential to each request a grant allows; no token enters the sandbox and none is needed. If the user sees no Git access tab on the sandbox's page, this deployment gives sandboxes no managed git access. Grants work only in `rules` network mode.\n\n- Use a plain remote with no credential in it: `\u003Cscheme>:\u002F\u002F\u003Cgit-host>\u002F\u003Cgroup>\u002F\u003Cproject>.git`. Always end it in `.git`, give at least group and project (nested groups are fine), and use the path's exact casing as the grant shows it.\n- Use the scheme the git host itself serves (`http` or `https`): the host side keeps the port your remote names, so the other scheme fails. Take it from the host's own clone URL, or from `git -C ~\u002Fwork\u002Frepository remote get-url origin` on a sandbox created with Open repository.\n- Never put a token in the URL, `~\u002F.netrc`, a credential helper, a git config or an `Authorization` or `PRIVATE-TOKEN` header for a granted host: depending on the host it is discarded or it stops the owner's credential from being added.\n- The base image has no `glab` or `gh`; use `git`, `curl` and `jq`.\n- Run git with `GIT_TERMINAL_PROMPT=0` (the sandbox does not set it), so an authentication failure ends the command instead of waiting for a username.\n- Git LFS is not supported: its requests are refused.\n\n## What is granted\n\nRun `curl -s -w '\\n%{http_code}\\n' \u003Cscheme>:\u002F\u002F\u003Cgit-host>\u002F_cogbox\u002Fgrants`. A `200` with a JSON `grants` list is this sandbox's live grants on that host, answered on the host side with no secret in it. Each grant has `scope` (`project`, `namespace` or `instance`), `repo` (`group\u002Fproject` or `group\u002F*`; absent on `instance`), `caps` (such as `git-read` and `git-write`) and, only when push rules apply, `push_refs`, `push_deny_delete` and `push_deny_tags`.\n\nA `403` whose body is `cogbox-l7: denied`, or an empty `403` with `X-Cogbox-Deny: no_route`, means this host has no discovery: try the repository with `GIT_TERMINAL_PROMPT=0 git ls-remote \u003Cremote>`, and ask the owner what is granted only if that fails. A page from the git host itself (no `X-Cogbox-Deny`) means the request reached the git host directly, usually because no grant is live for that host name: check that you used the exact host name the grant names, try `git ls-remote` the same way, then ask the owner. `000` (no HTTP response at all; git says `TLS connect error` or `Empty reply from server`) means either the remote uses a scheme the git host does not serve (an `https` remote to an `http` git host gets no response at all) or no grant is live for this sandbox on that host and its address is blocked: retry with the scheme from the host's own clone URL, then ask for the grant's status (below). Just after a start, a restart or an unshare, `000` and then a page from the git host itself can last a few seconds even while the tab reads `active`: wait about 15 seconds and retry once before acting on either.\n\nUnder a namespace grant with git read, on a host with discovery, `curl -s '\u003Cscheme>:\u002F\u002F\u003Cgit-host>\u002Fapi\u002Fv4\u002Fgroups\u002F\u003Cgroup-path>\u002Fprojects?per_page=100&page=1' | jq -r '.[].path_with_namespace'` lists its projects, with every `\u002F` in the group path written as `%2F` (for `acme\u002Fiac\u002F*`, `acme%2Fiac`). Raise `page` until a page lists fewer than 100; `&search=\u003Cname>` narrows it.\n\n## Pushing\n\nThe base image sets no commit identity: if `git config user.email` prints nothing, ask the user which name and email to commit as and set them with `git config` in that repository; never invent one.\n\nPushing needs `git-write` on a grant that covers the repository. Push rules exist only on hosts with discovery. A `push_refs` pattern matches whole `\u002F` components (`*` exactly one, `**` one or more), starts with `refs\u002Fheads\u002F` or `refs\u002Ftags\u002F`, and is case-sensitive; push to a ref that matches, for example `git push origin HEAD:refs\u002Fheads\u002Fagent\u002F\u003Ctopic>`. With no `push_refs` any branch may be pushed. Under a grant with push rules, a signed push (`--signed`) is refused, `push_deny_delete` and `push_deny_tags` refuse deletions and tags, and one refused ref refuses the whole push.\n\nPush rules cannot tell a force-push from a normal push, and merging a merge request through the API moves its target branch with no push at all; the git host's protected branches are the only guard. Do not force-push, rewrite pushed history or merge unless the user asked for it.\n\n## The git host API\n\nCall it as `curl -s \u003Cscheme>:\u002F\u002F\u003Cgit-host>\u002Fapi\u002Fv4\u002F...` with no credential. Send request bodies as JSON with `-H 'Content-Type: application\u002Fjson'`, always send a body on POST and PUT (`--data '{}'` when there is nothing else), and never use `private_token`, `access_token` or `job_token` query parameters.\n\nResolve a project's numeric id with `curl -s '\u003Cscheme>:\u002F\u002F\u003Cgit-host>\u002Fapi\u002Fv4\u002Fprojects\u002F\u003Cpath>' | jq '{id, default_branch}'`, with every `\u002F` in the project path written as `%2F` (`acme%2Fiac%2Fapp`), and address it by that id; if the id is refused with `scope_mismatch`, use the encoded path form instead. Print only the fields you need: a project object, job logs and artifacts can carry secrets, so never dump them whole. Change repository content with `git push`: API writes to commits, files, branches or tags, and every DELETE, are refused.\n\n## When a request fails\n\n`curl -s -o \u002Fdev\u002Fnull -D - '\u003Curl>' | grep -i -e '^HTTP\u002F' -e '^x-cogbox-deny'` prints the status and, when the sandbox's host side refused it, the reason. For a push: `GIT_TRACE_CURL=1 GIT_TERMINAL_PROMPT=0 git push \u003Cargs> 2>&1 | grep -i 'x-cogbox-deny'`. Never print whole traces or header dumps.\n\n| What you see | Meaning | Do |\n|---|---|---|\n| `X-Cogbox-Deny: cap_missing` | no grant has that capability (e.g. push without git write) | ask the owner to extend the grant |\n| `X-Cogbox-Deny: scope_mismatch` | grants have the capability, none covers this repository | check path and casing, then ask the owner |\n| `ref_denied`, `push_cert_unsupported`, `too_many_refs`, `push_malformed` | a push rule refused the whole push | push to an allowed ref, unsigned, fewer refs at once |\n| `no_route`, `method_not_allowed`, `service_invalid` | that path or method is not forwarded (LFS, the instance-wide project list, GraphQL, DELETE, API repository writes) | use git or a forwarded endpoint |\n| `form-body`, `missing_length_on_body_method`, `forbidden-query` | request shape refused | JSON body with its content type, a body on POST and PUT, no token in the query |\n| `no_grant`, `no-policy`, `cred-unavailable`, `CredentialUnavailable` | nothing is live for this host now | just after a start, wait a little and retry once; if it persists, ask for the grant's status on the Git access tab and act on it (below), and if it reads `active`, ask the owner to restart the sandbox |\n| `overloaded` (503) | more than 8 requests at once | retry one at a time |\n| 403 with body `cogbox-l7: denied` | a host without discovery: URL not covered (missing `.git`, wrong casing) or capability missing | fix the URL, then ask the owner |\n| 403 with body `cogbox-l7: auth proxy unavailable` or `cogbox-l7: credential unavailable` | the host side refused to send the request without the owner's credential | do not retry in a loop; ask for the grant's status (below), and if it is `active`, ask the owner to restart the sandbox |\n| no HTTP response (`curl -w '%{http_code}'` prints `000`; git says `TLS connect error` or `Empty reply from server`) | a scheme the git host does not serve, or no grant is live on this host and its address is blocked | switch to the host's own scheme; if it is right, ask the user for the grant's status |\n| the git host's own 401, 403 or 404, no `X-Cogbox-Deny` | the git host decided: no grant reached it, the owner's account lacks access, or a protected branch refused | ask the owner |\n| a 502 on every request | (on any backend but the container) the host side's git proxy has stopped or failed upstream, which a scheme mismatch can also cause; its `X-Cogbox-Deny`, if any, names the upstream error | check the scheme against the host's clone URL; if it is right, ask the owner to restart the sandbox |\n\nUnder a grant reading `limited, restart needed`, a refusal of anything the grant allows, whatever it says (`no_route`, `cap_missing` or `cogbox-l7: denied`), is lifted by a restart.\n\n## Status on the Git access tab and what to ask for\n\nAsk the user for the grant's status on the Git access tab and act on it: `active` (live); `activating` or `activates on start` (wait, or start the sandbox); `pending` (the owner is not connected yet, or the sandbox is not running); `expired` (the owner extends it with \"Edit\"); `suspended (shared)` (sharing the sandbox pauses every grant until it is private again); `reconnect needed` (the owner presses \"Reconnect\" on that grant's row); `not found` (the owner's account cannot see that path); `restart needed` or `limited, restart needed` (restart the sandbox); `error, retrying` (wait, and restart only if it persists). A brief 401 right after the owner's token is refreshed heals by itself. The suspension while shared is deliberate, so that people the sandbox is shared with cannot act as the owner: never suggest a token or an injected secret to get around it; the owner unshares it, or the work moves to a sandbox that is not shared.\n\nOnly the owner adds or changes grants, with no admin approval; users the sandbox is shared with cannot. Tell the owner exactly what to grant: the repository as `group\u002Fproject` or `group\u002F*` (every project in the group and its subgroups); the capabilities, each `read` or `write` (`git`, `issues`, `merge requests`, `pipelines`, `wiki`; `repository API` is read only); for pushes optionally \"only refs matching\" with whole-component patterns such as `refs\u002Fheads\u002Fagent\u002F*` (`refs\u002Ftags\u002Fv*` is not valid); and an expiry; they save it with \"Grant\". To open a merge request, ask for `merge requests` write plus `git` write to push its source branch; `merge requests` also offers `merge`, which approves and merges as the owner, so ask for it only when the user wants that. If the provider shows \"coarse access\" on the Git access tab, only `git` read or write, `issues` and `merge requests` exist (the last includes merge) and there are no push rules; ask for those.\n\n## SSH remotes, other hosts, Open repository\n\nSSH remotes (`git@\u003Cgit-host>:...`, `ssh:\u002F\u002F...`) never get a host credential. They work only with the user's own SSH agent forwarded over the cogworx SSH gateway (`ssh -A`; load `cogbox-remote-access`) and when the git host's port 22 is reachable (public addresses are by default; a private one needs an IP-range rule, load `cogbox-network`). Prefer a granted `http`\u002F`https` remote.\n\nA git host cogworx does not manage gets no grants: public repositories clone anonymously, and for private ones the owner can bind a credential for that host as an injected secret (Secrets page \"+ Bind secret\": \"Kind\" `basic` with a user name as \"Username\" and a token as \"Password\", and \"Inject into requests to this host\"; load `cogbox-network`).\n\nA sandbox created with Open repository (container, gcp and proxmox sandboxes only) has the project's default branch checked out at `~\u002Fwork\u002Frepository` and a read-only grant for that project; pushing from it needs the owner to add git write to that grant.\n\n## Local mode\n\nThere are no grants and no `\u002F_cogbox\u002Fgrants`. Public repositories clone anonymously over https; a git host on a private address is blocked until the user adds a rule on their host (load `cogbox-network`). For private repositories the user binds a credential on their workstation with `cogbox secret add \u003Csecret> --from-file \u003Cfile> --audience \u003Cgit-host> --kind basic --inject -n \u003Cname>` (value `user:token`; it applies to the whole host; for the `default` instance omit `-n \u003Cname>` and run `cogbox secret reload` afterwards). Never ask for the token here and never run `cogbox` in this guest.\n","Read `\u002Frun\u002Fcogbox\u002Fenvironment.json` as `cogbox-environment` describes. `cogworx`: everything below applies except the last section. `local`: only the last section applies. `unknown`, missing or malformed: ask whether the user runs local cogbox or a managed cogworx sandbox before giving git-access instructions.\n\nIf an installed plugin ships a skill for a particular git host (the `cogbox-plugins` skill lists them with their plugin), use it for that host's specifics; the credential rules in this skill still apply to every host.\n\n## Remotes and credentials\n\nIn cogworx, repository access comes from grants the sandbox's owner makes on its Git access tab, for git hosts the operator connected to cogworx (GitLab API hosts). The host side adds the owner's credential to each request a grant allows; no token enters the sandbox and none is needed. If the user sees no Git access tab on the sandbox's page, this deployment gives sandboxes no managed git access. Grants work only in `rules` network mode.\n\n- Use a plain remote with no credential in it: `\u003Cscheme>:\u002F\u002F\u003Cgit-host>\u002F\u003Cgroup>\u002F\u003Cproject>.git`. Always end it in `.git`, give at least group and project (nested groups are fine), and use the path's exact casing as the grant shows it.\n- Use the scheme the git host itself serves (`http` or `https`): the host side keeps the port your remote names, so the other scheme fails. Take it from the host's own clone URL, or from `git -C ~\u002Fwork\u002Frepository remote get-url origin` on a sandbox created with Open repository.\n- Never put a token in the URL, `~\u002F.netrc`, a credential helper, a git config or an `Authorization` or `PRIVATE-TOKEN` header for a granted host: depending on the host it is discarded or it stops the owner's credential from being added.\n- The base image has no `glab` or `gh`; use `git`, `curl` and `jq`.\n- Run git with `GIT_TERMINAL_PROMPT=0` (the sandbox does not set it), so an authentication failure ends the command instead of waiting for a username.\n- Git LFS is not supported: its requests are refused.\n\n## What is granted\n\nRun `curl -s -w '\\n%{http_code}\\n' \u003Cscheme>:\u002F\u002F\u003Cgit-host>\u002F_cogbox\u002Fgrants`. A `200` with a JSON `grants` list is this sandbox's live grants on that host, answered on the host side with no secret in it. Each grant has `scope` (`project`, `namespace` or `instance`), `repo` (`group\u002Fproject` or `group\u002F*`; absent on `instance`), `caps` (such as `git-read` and `git-write`) and, only when push rules apply, `push_refs`, `push_deny_delete` and `push_deny_tags`.\n\nA `403` whose body is `cogbox-l7: denied`, or an empty `403` with `X-Cogbox-Deny: no_route`, means this host has no discovery: try the repository with `GIT_TERMINAL_PROMPT=0 git ls-remote \u003Cremote>`, and ask the owner what is granted only if that fails. A page from the git host itself (no `X-Cogbox-Deny`) means the request reached the git host directly, usually because no grant is live for that host name: check that you used the exact host name the grant names, try `git ls-remote` the same way, then ask the owner. `000` (no HTTP response at all; git says `TLS connect error` or `Empty reply from server`) means either the remote uses a scheme the git host does not serve (an `https` remote to an `http` git host gets no response at all) or no grant is live for this sandbox on that host and its address is blocked: retry with the scheme from the host's own clone URL, then ask for the grant's status (below). Just after a start, a restart or an unshare, `000` and then a page from the git host itself can last a few seconds even while the tab reads `active`: wait about 15 seconds and retry once before acting on either.\n\nUnder a namespace grant with git read, on a host with discovery, `curl -s '\u003Cscheme>:\u002F\u002F\u003Cgit-host>\u002Fapi\u002Fv4\u002Fgroups\u002F\u003Cgroup-path>\u002Fprojects?per_page=100&page=1' | jq -r '.[].path_with_namespace'` lists its projects, with every `\u002F` in the group path written as `%2F` (for `acme\u002Fiac\u002F*`, `acme%2Fiac`). Raise `page` until a page lists fewer than 100; `&search=\u003Cname>` narrows it.\n\n## Pushing\n\nThe base image sets no commit identity: if `git config user.email` prints nothing, ask the user which name and email to commit as and set them with `git config` in that repository; never invent one.\n\nPushing needs `git-write` on a grant that covers the repository. Push rules exist only on hosts with discovery. A `push_refs` pattern matches whole `\u002F` components (`*` exactly one, `**` one or more), starts with `refs\u002Fheads\u002F` or `refs\u002Ftags\u002F`, and is case-sensitive; push to a ref that matches, for example `git push origin HEAD:refs\u002Fheads\u002Fagent\u002F\u003Ctopic>`. With no `push_refs` any branch may be pushed. Under a grant with push rules, a signed push (`--signed`) is refused, `push_deny_delete` and `push_deny_tags` refuse deletions and tags, and one refused ref refuses the whole push.\n\nPush rules cannot tell a force-push from a normal push, and merging a merge request through the API moves its target branch with no push at all; the git host's protected branches are the only guard. Do not force-push, rewrite pushed history or merge unless the user asked for it.\n\n## The git host API\n\nCall it as `curl -s \u003Cscheme>:\u002F\u002F\u003Cgit-host>\u002Fapi\u002Fv4\u002F...` with no credential. Send request bodies as JSON with `-H 'Content-Type: application\u002Fjson'`, always send a body on POST and PUT (`--data '{}'` when there is nothing else), and never use `private_token`, `access_token` or `job_token` query parameters.\n\nResolve a project's numeric id with `curl -s '\u003Cscheme>:\u002F\u002F\u003Cgit-host>\u002Fapi\u002Fv4\u002Fprojects\u002F\u003Cpath>' | jq '{id, default_branch}'`, with every `\u002F` in the project path written as `%2F` (`acme%2Fiac%2Fapp`), and address it by that id; if the id is refused with `scope_mismatch`, use the encoded path form instead. Print only the fields you need: a project object, job logs and artifacts can carry secrets, so never dump them whole. Change repository content with `git push`: API writes to commits, files, branches or tags, and every DELETE, are refused.\n\n## When a request fails\n\n`curl -s -o \u002Fdev\u002Fnull -D - '\u003Curl>' | grep -i -e '^HTTP\u002F' -e '^x-cogbox-deny'` prints the status and, when the sandbox's host side refused it, the reason. For a push: `GIT_TRACE_CURL=1 GIT_TERMINAL_PROMPT=0 git push \u003Cargs> 2>&1 | grep -i 'x-cogbox-deny'`. Never print whole traces or header dumps.\n\n| What you see | Meaning | Do |\n|---|---|---|\n| `X-Cogbox-Deny: cap_missing` | no grant has that capability (e.g. push without git write) | ask the owner to extend the grant |\n| `X-Cogbox-Deny: scope_mismatch` | grants have the capability, none covers this repository | check path and casing, then ask the owner |\n| `ref_denied`, `push_cert_unsupported`, `too_many_refs`, `push_malformed` | a push rule refused the whole push | push to an allowed ref, unsigned, fewer refs at once |\n| `no_route`, `method_not_allowed`, `service_invalid` | that path or method is not forwarded (LFS, the instance-wide project list, GraphQL, DELETE, API repository writes) | use git or a forwarded endpoint |\n| `form-body`, `missing_length_on_body_method`, `forbidden-query` | request shape refused | JSON body with its content type, a body on POST and PUT, no token in the query |\n| `no_grant`, `no-policy`, `cred-unavailable`, `CredentialUnavailable` | nothing is live for this host now | just after a start, wait a little and retry once; if it persists, ask for the grant's status on the Git access tab and act on it (below), and if it reads `active`, ask the owner to restart the sandbox |\n| `overloaded` (503) | more than 8 requests at once | retry one at a time |\n| 403 with body `cogbox-l7: denied` | a host without discovery: URL not covered (missing `.git`, wrong casing) or capability missing | fix the URL, then ask the owner |\n| 403 with body `cogbox-l7: auth proxy unavailable` or `cogbox-l7: credential unavailable` | the host side refused to send the request without the owner's credential | do not retry in a loop; ask for the grant's status (below), and if it is `active`, ask the owner to restart the sandbox |\n| no HTTP response (`curl -w '%{http_code}'` prints `000`; git says `TLS connect error` or `Empty reply from server`) | a scheme the git host does not serve, or no grant is live on this host and its address is blocked | switch to the host's own scheme; if it is right, ask the user for the grant's status |\n| the git host's own 401, 403 or 404, no `X-Cogbox-Deny` | the git host decided: no grant reached it, the owner's account lacks access, or a protected branch refused | ask the owner |\n| a 502 on every request | (on any backend but the container) the host side's git proxy has stopped or failed upstream, which a scheme mismatch can also cause; its `X-Cogbox-Deny`, if any, names the upstream error | check the scheme against the host's clone URL; if it is right, ask the owner to restart the sandbox |\n\nUnder a grant reading `limited, restart needed`, a refusal of anything the grant allows, whatever it says (`no_route`, `cap_missing` or `cogbox-l7: denied`), is lifted by a restart.\n\n## Status on the Git access tab and what to ask for\n\nAsk the user for the grant's status on the Git access tab and act on it: `active` (live); `activating` or `activates on start` (wait, or start the sandbox); `pending` (the owner is not connected yet, or the sandbox is not running); `expired` (the owner extends it with \"Edit\"); `suspended (shared)` (sharing the sandbox pauses every grant until it is private again); `reconnect needed` (the owner presses \"Reconnect\" on that grant's row); `not found` (the owner's account cannot see that path); `restart needed` or `limited, restart needed` (restart the sandbox); `error, retrying` (wait, and restart only if it persists). A brief 401 right after the owner's token is refreshed heals by itself. The suspension while shared is deliberate, so that people the sandbox is shared with cannot act as the owner: never suggest a token or an injected secret to get around it; the owner unshares it, or the work moves to a sandbox that is not shared.\n\nOnly the owner adds or changes grants, with no admin approval; users the sandbox is shared with cannot. Tell the owner exactly what to grant: the repository as `group\u002Fproject` or `group\u002F*` (every project in the group and its subgroups); the capabilities, each `read` or `write` (`git`, `issues`, `merge requests`, `pipelines`, `wiki`; `repository API` is read only); for pushes optionally \"only refs matching\" with whole-component patterns such as `refs\u002Fheads\u002Fagent\u002F*` (`refs\u002Ftags\u002Fv*` is not valid); and an expiry; they save it with \"Grant\". To open a merge request, ask for `merge requests` write plus `git` write to push its source branch; `merge requests` also offers `merge`, which approves and merges as the owner, so ask for it only when the user wants that. If the provider shows \"coarse access\" on the Git access tab, only `git` read or write, `issues` and `merge requests` exist (the last includes merge) and there are no push rules; ask for those.\n\n## SSH remotes, other hosts, Open repository\n\nSSH remotes (`git@\u003Cgit-host>:...`, `ssh:\u002F\u002F...`) never get a host credential. They work only with the user's own SSH agent forwarded over the cogworx SSH gateway (`ssh -A`; load `cogbox-remote-access`) and when the git host's port 22 is reachable (public addresses are by default; a private one needs an IP-range rule, load `cogbox-network`). Prefer a granted `http`\u002F`https` remote.\n\nA git host cogworx does not manage gets no grants: public repositories clone anonymously, and for private ones the owner can bind a credential for that host as an injected secret (Secrets page \"+ Bind secret\": \"Kind\" `basic` with a user name as \"Username\" and a token as \"Password\", and \"Inject into requests to this host\"; load `cogbox-network`).\n\nA sandbox created with Open repository (container, gcp and proxmox sandboxes only) has the project's default branch checked out at `~\u002Fwork\u002Frepository` and a read-only grant for that project; pushing from it needs the owner to add git write to that grant.\n\n## Local mode\n\nThere are no grants and no `\u002F_cogbox\u002Fgrants`. Public repositories clone anonymously over https; a git host on a private address is blocked until the user adds a rule on their host (load `cogbox-network`). For private repositories the user binds a credential on their workstation with `cogbox secret add \u003Csecret> --from-file \u003Cfile> --audience \u003Cgit-host> --kind basic --inject -n \u003Cname>` (value `user:token`; it applies to the whole host; for the `default` instance omit `-n \u003Cname>` and run `cogbox secret reload` afterwards). Never ask for the token here and never run `cogbox` in this guest.\n",{"name":5,"description":7},"master","9054adffa53fa7af94439dff72b432e11499a008","skills\u002Fcogbox-git",1,"https:\u002F\u002Fgithub.com\u002Fillustris\u002Fcogbox","https:\u002F\u002Fgithub.com\u002Fillustris","https:\u002F\u002Fillustris.tech","2026-11-10 00:38:16",{"source":8,"skillName":5,"commands":52,"prompt":62,"zipAvailable":63},[53,56,59],{"tool":54,"command":55},"npx","npx skills add illustris\u002Fcogbox --skill cogbox-git",{"tool":57,"command":58},"bunx","bunx skills add illustris\u002Fcogbox --skill cogbox-git",{"tool":60,"command":61},"pnpm","pnpm dlx skills add illustris\u002Fcogbox --skill cogbox-git","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fillustris\u002Fcogbox\u002Fblob\u002Fmaster\u002Fskills\u002Fcogbox-git\u002FSKILL.md",true,[],[66,81,94,108,121,129],{"skillNo":67,"name":68,"nameZh":6,"description":69,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":70,"categories":71,"keywords":72,"publishedAt":38},"01M71CHP4B6XX9PAZ5JRQV8E58","app-relay","Legacy plugin guidance for migration testing.","https:\u002F\u002Fgithub.com\u002Fillustris\u002Fcogbox\u002Fblob\u002Fmaster\u002Ftests\u002Ffixtures\u002Fnative-app\u002Flegacy-contents\u002Fskills\u002Fapp-relay\u002FSKILL.md",[],[73,74,75,76,77,78,79,35,80],"app","app relay","relay","guidance","migration","plugin","Legacy","testing",{"skillNo":82,"name":83,"nameZh":6,"description":84,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":85,"categories":86,"keywords":87,"publishedAt":38},"01M71CHM675ZZTJ9HRGHPWVVZS","demo-overview","Overview of the demo backend; start here before answering demo questions.","https:\u002F\u002Fgithub.com\u002Fillustris\u002Fcogbox\u002Fblob\u002Fmaster\u002Ftests\u002Ffixtures\u002Fbrain-plugin\u002Fcontents\u002Fskills\u002Fdemo-overview\u002FSKILL.md",[],[88,89,90,91,92,93],"overview","demo overview","demo","questions","backend","start",{"skillNo":95,"name":96,"nameZh":6,"description":97,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":98,"categories":99,"keywords":100,"publishedAt":38},"01M71CHJNH0AX8E74WBGJH1JMR","demo-es","Query the demo Elasticsearch cluster: es-search, es-cat.","https:\u002F\u002Fgithub.com\u002Fillustris\u002Fcogbox\u002Fblob\u002Fmaster\u002Ftests\u002Ffixtures\u002Fbrain-plugin\u002Fcontents\u002Fskills\u002Fdemo-es\u002FSKILL.md",[],[90,101,102,103,104,105,106,107],"es","demo es","search","query","cat","cluster","elasticsearch",{"skillNo":109,"name":110,"nameZh":6,"description":111,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":112,"categories":113,"keywords":114,"publishedAt":38},"01M71CHGPNHSBFJHCQRSMNHS3E","cogbox-plugins","Fixture skill squatting on the name cogbox reserves for its index.","https:\u002F\u002Fgithub.com\u002Fillustris\u002Fcogbox\u002Fblob\u002Fmaster\u002Ftests\u002Ffixtures\u002Fbrain-collide\u002Freserved\u002Fskills\u002Fcogbox-plugins\u002FSKILL.md",[],[115,116,117,118,35,119,120],"cogbox plugins","plugins","fixture","index","name","fixture skill",{"skillNo":122,"name":116,"nameZh":6,"description":123,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":124,"categories":125,"keywords":126,"publishedAt":38},"01M71CHERNF4GWZ1C34MHKKN19","Fixture skill named `plugins`, shipped by a second, unrelated plugin.","https:\u002F\u002Fgithub.com\u002Fillustris\u002Fcogbox\u002Fblob\u002Fmaster\u002Ftests\u002Ffixtures\u002Fbrain-collide\u002Freserved-qual-b\u002Fskills\u002Fplugins\u002FSKILL.md",[],[116,120,117,78,127,128],"unrelated","second",{"skillNo":130,"name":116,"nameZh":6,"description":131,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":132,"categories":133,"keywords":134,"publishedAt":38},"01M71CHDPMR9KDE5QP6H3W66CW","Fixture skill named `plugins`, shipped by a plugin installed as `cogbox`.","https:\u002F\u002Fgithub.com\u002Fillustris\u002Fcogbox\u002Fblob\u002Fmaster\u002Ftests\u002Ffixtures\u002Fbrain-collide\u002Freserved-qual-a\u002Fskills\u002Fplugins\u002FSKILL.md",[],[116,117,135,78,120],"as"]