GitHub remote dry-run rule
The initial package exports the GitHub remote orchestration rule in dry-run
mode. Running the free rule here distributes the entire scriptmodule.
$ run-function CommonsBase_Remote.GitHub.F_DryRunPlan@0.2.0 -f ${RUNTIME}/GitHub-0.2.0.plan.txt dry_run=true timestamp=20260527165106 repo=github.com/OWNER/REPO cmd=get-bundle commandvsl='get-bundle MlFront_Std.Sample.Abc@1.0.0' 'argv[]=get-bundle' 'argv[]=MlFront_Std.Sample.Abc@1.0.0'
\test(pass)
\dk.asset(path: "dry-run.txt", value-id: "atrrfkfvw2xzmtpbzzgucakqw4atdt2jtz7hbrgyjpt5hrjy7ioza", byteSize: "794")\;
The remote command (host side)
`dk0 remote UI_MODULE@VERSION [OPTION=VALUE...] [REPOSITORY] INNER_COMMAND...`
is thin sugar in the `dk0` host (`ShellRemote.ml`) over a plain
`dk0 run <rule>` of this orchestration rule. The host does not run the inner
command locally; it only forwards it. Concretely, `remote`:
1. **Resolves the rule.** The `UI_MODULE@VERSION` is expanded to the full rule
id: a bare name like `GitHub@0.1.0` becomes
`CommonsBase_Remote.GitHub.Run@0.1.0` (the `_Remote` library suffix and the
`.Run` rule are added when missing).
2. **Splits arguments.** Leading `OPTION=VALUE` pairs are separated from the
inner command, an optional `REPOSITORY` before a recognized inner command is
detected, and the inner command name is checked against the supported list
(`get-object`, `run-object`, `run-function`, `run-rule`, `enter-object`,
`merge-object`, `get-asset`, `run-asset`, `get-bundle`, `test`, `lua`,
`dialog`, `exec`, `run`).
3. **Computes a requested trace key** for commands that produce
dependency-bearing values (`get-object`, `run-object`, `run-function`,
`run-rule`, `enter-object`, `merge-object`). Bundles and assets have no
dependencies, so they carry no requested trace key.
4. **Builds the rule request parameters** and runs
`dk0 run CommonsBase_Remote.GitHub.Run@... <params>`, where the params are:
- `cmd=<inner command name>` and `commandvsl=<inner command as one quoted
line>` (the human-readable audit line),
- `requested_trace_key_id=...` / `requested_trace_key_description=...` when
applicable,
- the forwarded `OPTION=VALUE` remote options, `repo=<REPOSITORY>`, and
`project_root=<absolute project directory>`,
- **`argv[]=<token>` for every token of the inner command.** The argv is
forwarded verbatim; the runner's `dk0` re-parses it and resolves any
`$(...)`/`${...}` subshells and variables against the **remote** workspace,
never the local one. Local argument expansion is intentionally not applied
to the `remote` path.
So everything below happens inside the `Run` rule, driven by those request
parameters.
GitHub remote execution flow
The GitHub remote rule is designed so the user's project tree is only an input source. All remote-session git operations happen in the isolated commit directory `.dk/r/c` with commands such as `git -C .dk/r/c fetch`, `git -C .dk/r/c add`, and `git -C .dk/r/c push`. The user's project may have a different git remote, or may not be a git checkout at all.
Consumer validation workflow
When validating GitHub remote behavior from another project, do not point `dk0` at an unreleased local checkout with an ad hoc include path like `-I some/source/CommonsBase_Remote/etc/dk/v`. The reviewed workflow is: 1. (Diskuv owns this step) Release `CommonsBase_Remote` from its package repository with the normal commit, tag, push, and GitHub release flow. 2. In the consumer project, import that released package with: ```text ./dk0 add github-l2 dkpkg/CommonsBase_Remote
- Run the consumer's
dk0 remote ...smoke against the imported release.
That keeps the validation path aligned with how end users consume the GitHub remote package.
The detailed orchestration has three phases:
Bootstrap and local staging
- Ensure the repository exists and has the remote-session branches
dk-session-rootanddk-session-<i>. - Ensure the repository has trusted recipient metadata:
DK_SESSION_KEYstays in a GitHub secret.dk_session_recipientanddk_session_recipient_sigstay in GitHub repository variables.- The local orchestrator verifies the recipient signature before encrypting any staged payload.
- Populate the isolated commit directory
.dk/r/cfrom the user project, including copies of:dk.udk0anddk0.cmd- optional
etc/dk/{d,i,v}
- Use
.dk/r/c/t/{k,c,d}as the isolated key, cache, and data directories for localdk0operations in the commit directory. - Commit the signify verify public key into
.dk/r/cso the GitHub runner can verify signed manifests without depending on GitHub variables for that key. - Run local
dk0 updateinside.dk/r/cto materialize the workspace inputs needed by the remote command. - If a retry left
.dk/r/cdirty, stash that leftover residue before the branch sync step sogit pull --rebasecan proceed on a clean tree. - Rebuild
.dk/r/c/.gitat the start of each submit attempt: if stale git metadata exists, delete it, then rungit -C .dk/r/c initand continue from that freshly initialized repository. This avoids falling back into the outer consumer repository when UI-runtime filesystem probes lag behind the just-created.gitdirectory. Only.dk/r/cmay have its git remote or session branches changed by this rule. - Resolve the local
dk0wrapper by absolute path from the staged snapshot when invoking it from UI submit code, since the rule runtime cwd may differ from the user project root. - When the local submit-side bootstrap needs
CommonsBase_Std.Coreutils, invoke the staged snapshotdk0wrapper while pointing-Iat the live projectetc/dk/idirectory so imported package metadata stays visible before.dk/r/c/etc/dk/ihas been fully materialized. - Resolve host tools (
git,gh) by probing the requested program first, then on Windows falling back to generated wrapper commands that extendPATHwith known install directories when direct lookup fails. - Identify local assets whose mirrors are all strictly inside the user project directory (via
request.ui.assets, which rejects any local origin that escapes the project root) and stage their source files for encryption.
- Ensure the repository exists and has the remote-session branches
Stage release publication
- Pick a free session branch by shuffling session numbers and skipping any session whose GitHub workflow is already running.
- Append the audited command line to the session audit file in
.dk/r/c. - Commit the stage control files in
.dk/r/c, including the audit line, the argument transport, the signed stage manifest, and.github/workflows/dk-session.<i>.yml. - Tag and push
0.1.<TS>-stage. - GitHub Actions creates a prerelease for the stage tag whose description is the audited command line.
- After the stage prerelease exists, the local orchestrator encrypts each local asset's source file for the verified
dk_session_recipientand uploads the ciphertext to that release. A committed manifest (covered by the signedINDEX) maps each encrypted blob to its local source path, and the runner is told to--trust-local-packageeach owning package.
Exec publication and result retrieval
- Commit the execution payload in
.dk/r/c, including the copied workspace files, the signedINDEX, the committed signify verify public key, and the workflow file. - Tag and push
0.1.<TS>-exec. - GitHub Actions verifies
INDEX.sigand theINDEXchecksums with the committed signify public key, then removes that public key (the matching secret is never shipped) so the runner'sdk0generates its own ephemeral build keypair, runs the requested value command ortest/lua/runcommand, and writes a single combined result filedk-session-result.txt(the remote exit code plus delimited stdout/stderr — one always-non-empty file, because GitHub cannot upload zero-byte release assets). It uploads that file to the exec prerelease. - The local orchestrator waits for the exec workflow run matching the pushed commit (
headSha), downloadsdk-session-result.txt, prints the remote stdout/stderr, and propagates the remote exit code. - For local-asset commands, GitHub Actions decrypts each staged source with the
DK_SESSION_KEYsecret into its project-relative path (per the signed manifest, rejecting absolute or parent-relative paths) before running, so remoteget-asset/run-object/get-bundleof local assets resolve their content. Commands needing only the committed workspace (e.g.lua,test) ship no encrypted assets.
- Commit the execution payload in
Files needed in the project tree
| Path | Why needed |
|---|---|
dk.u | Lists all the project directories needed remotely |
dk0 / dk0.cmd | Wrappers for local asset creation and remote command execution |
Files placed into the project tree
The current reviewed layout places only the remote-control directory in the user project tree.
| Path | Why it is in the project tree |
|---|---|
.dk/r/.gitignore | Keeps the remote-control subtree out of the user's main git repository. |
.dk/r/c/ | Isolated commit directory used as the remote-session git repository. Every remote git command is scoped with git -C .dk/r/c .... |
.dk/r/c/.git/ | Git metadata for the isolated commit repository. This is intentionally separate from any repository the user may have at the project root. |
.dk/r/c/.gitignore | Well-defined ignore policy for local-only isolated-repo state: it ignores .local, t/k/build.sec, t/c/, and t/d/ so local secrets, cache, and valuestore data are never staged by the remote-session repo. |
.dk/r/c/dk.u | Copy of the user's workspace file so the remote session can reproduce the selected workspace inputs without reading from the original project tree at execution time. |
.dk/r/c/dk0 | POSIX wrapper copied from the user's project so GitHub Actions can invoke the same public wrapper logic inside the isolated commit repository. |
.dk/r/c/dk0.cmd | Windows wrapper copied from the user's project for parity with the committed remote-session payload. |
.dk/r/c/etc/dk/d/ | Optional copy of distribution metadata required by the selected workspace. |
.dk/r/c/etc/dk/i/ | Optional copy of import metadata required by the selected workspace. |
.dk/r/c/etc/dk/v/ | Optional copy of value metadata required by the selected workspace. |
.dk/r/c/.github/workflows/dk-session.<i>.yml | Required by GitHub Actions. The workflow must live at this exact path inside the isolated commit repository. |
.dk/r/c/t/k/ | Isolated temporary key material used by commit-repo-local staging. |
.dk/r/c/t/c/ | Isolated cache directory for commit-repo-local dk0 update and staging operations. |
.dk/r/c/t/d/ | Isolated data directory that holds the local valuestore used to create the staged a* and b* release assets. |
.dk/r/c/.local/ | Local-only binaries like coreutils |
The user's original dk.u, dk0, dk0.cmd, and optional etc/dk/{d,i,v} remain the source inputs. The copies under .dk/r/c are the remote-session payload.

