← Priority list

Handoff: GithubProxy typed Git operations paused at API publication approval

Execute `/code/workspace/handoff-workstream/TASK_PROXY_EXTEND.md`: extend the typed `githubproxy.api` contract and GithubProxy server/client RPC path so a tokenless Handoff publisher can create a working branch, create one multi-file UTF-8 write/delete commit, open a pull request with the existing typed API, and enqueue that pull request in GitHub's merge queue. Raw reads remain available through `GithubAccount.apiRequest`; raw GraphQL and ref writes must remain denied. The requested code PRs must be opened but not merged, their full local suites must pass, and their `kotlin.build (remote)` checks must be watched to green.

hf-2026-07-13-githubproxy-typed-git-operations

Edit handoff

Add dependency

Complete this handoff

Moves it out of every priority list and into ArchiveArea.

Handoff document

Markdown

Handoff: GithubProxy typed Git operations paused at API publication approval

Written 2026-07-13 UTC.

RE-VERIFY: This is a write-time snapshot. Before acting, re-check the API PR with gh pr view https://github.com/CodexCoder21Organization/GithubProxyApi/pull/14 --json state,mergeStateStatus,statusCheckRollup,mergedAt,headRefOid, inspect both local branches with git status --short && git rev-parse HEAD, and inspect the active build at https://buildtest.kotlin.build/run?id=000505e7. Fresh repository and buildtest state always wins.

Mission summary

Execute /code/workspace/handoff-workstream/TASK_PROXY_EXTEND.md: extend the typed githubproxy.api contract and GithubProxy server/client RPC path so a tokenless Handoff publisher can create a working branch, create one multi-file UTF-8 write/delete commit, open a pull request with the existing typed API, and enqueue that pull request in GitHub's merge queue. Raw reads remain available through GithubAccount.apiRequest; raw GraphQL and ref writes must remain denied. The requested code PRs must be opened but not merged, their full local suites must pass, and their kotlin.build (remote) checks must be watched to green.

The task text requested API 0.2.0, but fresh main already contained the rate-limit release at 0.2.0, so this work correctly uses the next version, 0.3.0.

What was found and done (the chain)

  1. Read the task, each repository README and recent log, server Guardrails.kt, the complete testing architecture, engineering philosophy, and review-red-flags documentation. The optional CLI was intentionally left untouched because the target consumer uses the typed API directly.
  2. Added API 0.3.0 contract methods and DTOs: Repository.createBranch(branchName, fromSha), Repository.commitFiles(branchName, message, changes), PullRequest.enqueue(), FileChange, and CommitResult. KDoc and README document create-only refs, UTF-8-only content, null-content deletion, non-forced fast-forward semantics, workflow/default-branch restrictions, and why merge-queue enqueue is safe while raw GraphQL stays denied.
  3. Confirmed the API contract test failed before the methods/types existed, then passed after the implementation. The complete API suite passed locally: 6/6 tests. The API change is committed, pushed, and open at https://github.com/CodexCoder21Organization/GithubProxyApi/pull/14.
  4. Implemented the server operations through the real GitHub REST/GraphQL surfaces and the sandbox client adapters. createBranch preflights the exact ref and never moves an existing ref. commitFiles reads the branch head and base tree, creates blobs/tree/one commit whose sole parent is the observed head, then PATCHes the non-default branch with force=false. enqueuePullRequest validates the PR base and calls GraphQL enqueuePullRequest with the PR node id and expected head OID, then returns the refreshed PR.
  5. Centralized the .github/workflows(?:/.*)? matcher so typed commits and passthrough use the same case-insensitive pattern. Added branch-name validation for ref namespaces, HEAD, traversal, lock-file names, controls, and other invalid Git ref syntax. Strengthened passthrough protection to deny creation as well as movement/deletion of raw refs; read passthrough remains allowed.
  6. Added one-scenario-per-file, real in-process GitHub fixture tests for the complete happy path, existing-branch refusal, default-branch create/commit refusals, workflow-path refusal, non-default-base enqueue refusal, ref-namespace refusal, and the real precompiled client + SJVM + isolated libp2p round-trip. The happy path verifies two blobs including actual multibyte UTF-8 (Héllo 👋), a null-SHA deletion, the correct sole parent, and force=false.
  7. All 16 server tests that do not import the unpublished API passed individually, including every legacy test. The only unrun scenario is tests/sandboxedGitOperationsRoundTripTest.kts, because it resolves githubproxy.api:github-proxy-api:0.3.0 from kotlin.directory. The full 17-test suite has therefore not yet been run.
  8. Publishing is the authorization boundary. The publish-maven-artifact skill requires explicit user confirmation before its --force upload, and no confirmation had been received at write time. To compile the direct server tests without publishing, build.kts is deliberately parked with a clearly marked temporary client dependency pin to API 0.2.0; the sandbox test itself remains pinned to 0.3.0 so it cannot produce a false pass.
  9. Preserved the in-flight server work in pushed commit https://github.com/CodexCoder21Organization/GithubProxyServerService/commit/f030fd9d4fdbc30706d0b20a7dbb1008dc5e9637 on feature/typed-git-operations. It is intentionally a WIP commit and no server PR exists yet.
  10. API CI run 000505e7 was initially called a wedge by build-watchman after 12 minutes at 0/0. Direct host evidence contradicted that diagnosis: /root/buildtest-data/runs/000505e7/run.json reported status=PENDING, dropletId=0, empty droplet IP, and no test specs, which is ordinary queue wait. The run was not deleted or redispatched.

Relevant PRs / refs

| Repository / state at write time | Branch / head | Reference | |---|---|---| | GithubProxyApi PR OPEN; remote check IN_PROGRESS in buildtest queue; merge state BLOCKED | feature/typed-git-operations / ef2649abfac95a2ec49cf8840ce8f817cd4b43c1 | https://github.com/CodexCoder21Organization/GithubProxyApi/pull/14 | | GithubProxyServerService pushed WIP; no PR; working tree clean | feature/typed-git-operations / f030fd9d4fdbc30706d0b20a7dbb1008dc5e9637 | https://github.com/CodexCoder21Organization/GithubProxyServerService/commit/f030fd9d4fdbc30706d0b20a7dbb1008dc5e9637 | | API buildtest queue entry | 000505e7, PENDING, dropletId=0 at write time | https://buildtest.kotlin.build/run?id=000505e7 | | Local-cache challenge | merged permanent record | https://github.com/CodexCoder21Organization/PlanRepository/blob/main/challenges/2026-07-13-2038-kompile-local-cache-reused-a-stale-maven-artifact-after.md | | Initial build-wedge report | superseded by the correction below | https://github.com/CodexCoder21Organization/PlanRepository/blob/main/challenges/2026-07-13-2107-the-githubproxyapi-pr-remote-check-buildtest-run-000505e7.md | | Build-watchman queue-wait correction | merged permanent record | https://github.com/CodexCoder21Organization/PlanRepository/blob/main/challenges/2026-07-13-2109-correction-to-challenges-2026-07-13-2107-the.md | | Missing Fabric credentials | merged permanent record | https://github.com/CodexCoder21Organization/PlanRepository/blob/main/challenges/2026-07-13-2108-the-hardware-fabric-processes-skill-requires-mtls-files.md |

Next steps

  1. Re-verify current state first using the commands in the banner. Confirm the API PR remains OPEN before pushing any API update.

  2. Obtain the user's explicit approval to publish githubproxy.api:github-proxy-api:0.3.0. Do not infer approval. After approval, publish from the clean API branch using the required skill command:

    ~/bin/coursier launch community.kotlin.maven.artifact.publishing:community-kotlin-maven-artifact-publishing:0.0.5 \
      -r https://kotlin.directory -- \
      --workspace /code/workspace/GithubProxyApi \
      --buildrule githubproxy.api.buildMaven \
      --api-url https://api.kotlin.directory/upload \
      --force
    
  3. In /code/workspace/GithubProxyServerService/build.kts, remove the TEMPORARY LOCAL TEST PIN comment and restore MavenPrebuilt2("githubproxy.api:github-proxy-api:0.3.0").

  4. Before any build, run git fetch origin && git rebase origin/main. Clear only the server's stale repo-specific local build cache if the newly published coordinate is not observed: rm -rf ~/.aibuildcaches/_code_workspace_GithubProxyServerService.

  5. Run scripts/test.bash --test tests/sandboxedGitOperationsRoundTripTest.kts, then the mandatory full suite scripts/test.bash --test .. Do not skip, disable, weaken, lower iterations, or raise timeouts.

  6. Delete generated jars/ and any other build artifacts. Stage the restored dependency, amend the WIP commit to a final message such as Add typed Git operations, and push with --force-with-lease.

  7. Immediately before opening the server PR, fetch/rebase on origin/main again, rerun the full suite, check existing PRs, and then open the GithubProxyServerService PR. Do not merge it.

  8. Watch both PRs with the watch-build skill. Treat PENDING with dropletId=0 as queue wait and do not delete it. If CI genuinely fails, reproduce and fix the owning code; never bypass protection.

  9. Once both PRs are green, perform the task's final test-comprehensiveness and adversarial reviews. One preliminary review already added the ref-namespace RPC test, true multibyte UTF-8 verification, raw ref-creation regression coverage, and corrected raw-ref refusal wording. Revisit the API README phrase atomic commitFiles: single-commit commitFiles is more precise because immutable Git objects can remain orphaned if the final atomic ref update is rejected.

  10. Apply any review fixes on the same OPEN branches (checking PR state first), rerun suites and CI, and report both PR URLs, API version 0.3.0, final head SHAs, and review findings fixed. Never merge the code PRs without explicit user approval.

Reusable / operational knowledge

  • Use ~/bin/coursier, never /usr/local/bin/coursier, for this workstream.
  • A source change may be hidden by kompile's per-repository local artifact cache. Clear only the affected repo key, not global caches, and retain the original red test as evidence.
  • The test-script validator rejects named helper functions with declared return types. A local lambda was used for byte-accurate HTTP line parsing in the multibyte UTF-8 fixture.
  • GitHub Enterprise uses REST at /api/v3 but GraphQL at /api/graphql; GithubHttp.toUrl now maps the typed enqueue request accordingly.
  • HardwareControlFabric was the preferred production-host diagnostic path, but this environment had no ~/.config/hardware-control-fabric credentials. SSH was used only after that verified failure.
  • Build-watchman's generic no-progress alarm is not authoritative for unassigned builds. Inspect run.json: PENDING plus dropletId=0 is queue wait, exactly as the task warned.