@eir-labs/coltrane 0.8.1 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/claude_invoker.d.ts +4 -0
- package/dist/src/claude_invoker.js +68 -0
- package/dist/src/claude_invoker.js.map +1 -1
- package/dist/src/cli.d.ts +1 -1
- package/dist/src/committed_work.d.ts +206 -0
- package/dist/src/committed_work.js +0 -0
- package/dist/src/committed_work.js.map +1 -0
- package/dist/src/genome_schema.d.ts +502 -0
- package/dist/src/genome_schema.js +185 -0
- package/dist/src/genome_schema.js.map +1 -1
- package/dist/src/institution_enforcement.d.ts +9 -0
- package/dist/src/institution_enforcement.js +25 -0
- package/dist/src/institution_enforcement.js.map +1 -1
- package/dist/src/institution_loader.d.ts +21 -1
- package/dist/src/institution_loader.js +83 -1
- package/dist/src/institution_loader.js.map +1 -1
- package/dist/src/loader.d.ts +3 -2
- package/dist/src/loader.js +9 -2
- package/dist/src/loader.js.map +1 -1
- package/dist/src/output_mirror.js +45 -30
- package/dist/src/output_mirror.js.map +1 -1
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/dist/src/worker.d.ts +6 -0
- package/dist/src/worker.js +37 -0
- package/dist/src/worker.js.map +1 -1
- package/dist/src/workspace.d.ts +89 -0
- package/dist/src/workspace.js +141 -0
- package/dist/src/workspace.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The working tree a gig runs in, obtained AFTER the claim.
|
|
3
|
+
*
|
|
4
|
+
* WHY THIS EXISTS. `drain-loop.sh` cloned a repository BEFORE claiming, from a `REPO_URL` fixed in
|
|
5
|
+
* the box's environment at provisioning. That made a per-gig fact a per-box one — the same category
|
|
6
|
+
* error as the `worker_agent` the venue design already removed — and it meant every gig an
|
|
7
|
+
* organization ever dispatched had to work in the same repository.
|
|
8
|
+
*
|
|
9
|
+
* The obvious repair, letting a gig name its own repository through `input_data`, was refused on
|
|
10
|
+
* review and the reasons are worth keeping close to the code:
|
|
11
|
+
*
|
|
12
|
+
* - `input_data` is authored under a gate asking "may this agent RUN this standard". That is not
|
|
13
|
+
* "may it WRITE this repository", and nobody had asked the second question.
|
|
14
|
+
* - `git clone` accepts `ext::sh -c '…'` as a URL. A gig-supplied string is command execution.
|
|
15
|
+
*
|
|
16
|
+
* So the STORE names the repository, on the claim, from a governed column. Nothing the gig carries
|
|
17
|
+
* can influence it, because there is no field in which to carry it.
|
|
18
|
+
*
|
|
19
|
+
* AND THE CREDENTIAL IS FETCHED PER GIG, against a live lease. Not held at boot, not in the
|
|
20
|
+
* container's environment, not the same one twice. A drain between gigs holds no git credential at
|
|
21
|
+
* all — which is the property the per-gig store credential already has, extended to the half that
|
|
22
|
+
* previously sat in a Fly secret for the life of the machine.
|
|
23
|
+
*/
|
|
24
|
+
/** What the mint endpoint answers with. `expires_at` is GitHub's hour, not our thirty-minute lease
|
|
25
|
+
* — carried through so a caller can see the difference rather than assume they match. */
|
|
26
|
+
export interface GitCredential {
|
|
27
|
+
token: string;
|
|
28
|
+
expires_at?: string;
|
|
29
|
+
}
|
|
30
|
+
export interface PreparedWorkspace {
|
|
31
|
+
/** Absolute path to the clone. The gig runs with this as cwd. */
|
|
32
|
+
dir: string;
|
|
33
|
+
/** Idempotent. Safe to call from a `finally` that may run after a partial failure. */
|
|
34
|
+
cleanup: () => void;
|
|
35
|
+
/**
|
|
36
|
+
* Hand the git credential back when the gig is done.
|
|
37
|
+
*
|
|
38
|
+
* A GitHub installation token is fixed at ONE HOUR and the lease that justified it is thirty
|
|
39
|
+
* minutes, so the git half outlives its own authority by at least 2x — and no revocation on our
|
|
40
|
+
* side can recall it. GitHub exposes exactly one way to end one early: DELETE
|
|
41
|
+
* /installation/token, authenticated WITH that token.
|
|
42
|
+
*
|
|
43
|
+
* Which means only a cooperative holder can do it. That is not a security control and must not be
|
|
44
|
+
* described as one: a compromised drain simply declines to call this. It is a hygiene measure for
|
|
45
|
+
* the ordinary case, and the ordinary case is every gig — a run that takes four minutes stops
|
|
46
|
+
* holding a live credential fifty-six minutes early.
|
|
47
|
+
*
|
|
48
|
+
* Best-effort by construction: a failure here must never fail a drained gig.
|
|
49
|
+
*/
|
|
50
|
+
revoke: () => Promise<void>;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Trade the venue credential for a git credential scoped to ONE gig's repository.
|
|
54
|
+
*
|
|
55
|
+
* The endpoint decides nothing: it asks the store whether this instance currently holds a live
|
|
56
|
+
* lease on this gig, and mints only for the repository the store names. So a stolen drain key
|
|
57
|
+
* yields nothing here unless the thief is also, right now, doing that gig's work.
|
|
58
|
+
*/
|
|
59
|
+
export declare function fetchGitCredential(endpoint: string, drainKey: string, instance: string, gigId: string): Promise<GitCredential>;
|
|
60
|
+
/**
|
|
61
|
+
* Shallow-clone `repoUrl` into a fresh temp directory.
|
|
62
|
+
*
|
|
63
|
+
* THE TOKEN NEVER TOUCHES DISK, and that is not incidental. Embedding it in the remote URL
|
|
64
|
+
* (`https://x-access-token:$TOKEN@github.com/…`) writes it verbatim into `.git/config` — inside the
|
|
65
|
+
* very tree the gig's seats then read and write, one `git remote -v` away from model context. A
|
|
66
|
+
* credential helper is consulted only when the server challenges, and reads the token from the
|
|
67
|
+
* helper's own environment at that moment.
|
|
68
|
+
*
|
|
69
|
+
* The helper is supplied through GIT_CONFIG_* rather than `-c`, because `git clone -c k=v` writes k
|
|
70
|
+
* into the NEW clone's .git/config — see the note at the call site. Scoped to `https://github.com`
|
|
71
|
+
* so a URL naming any other host is never offered the token.
|
|
72
|
+
*/
|
|
73
|
+
export declare function cloneInto(repoUrl: string, token: string): PreparedWorkspace;
|
|
74
|
+
/**
|
|
75
|
+
* Everything above, for one claimed gig — or null when the claim names no repository.
|
|
76
|
+
*
|
|
77
|
+
* NULL IS A NORMAL ANSWER, not a degraded one. An organization that declares no `repo_url` runs
|
|
78
|
+
* gigs that do not touch a working tree, and refusing to run them because a repository is absent
|
|
79
|
+
* would repeat the boot-time refusal this whole change removes. A gig that DOES need a tree will
|
|
80
|
+
* fail on its own terms, naming what it could not find, which is a better error than any this
|
|
81
|
+
* layer could invent.
|
|
82
|
+
*/
|
|
83
|
+
export declare function prepareWorkspace(opts: {
|
|
84
|
+
repoUrl: string | null | undefined;
|
|
85
|
+
gigId: string;
|
|
86
|
+
drainKey: string | undefined;
|
|
87
|
+
instance: string | undefined;
|
|
88
|
+
endpoint: string | undefined;
|
|
89
|
+
}): Promise<PreparedWorkspace | null>;
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The working tree a gig runs in, obtained AFTER the claim.
|
|
3
|
+
*
|
|
4
|
+
* WHY THIS EXISTS. `drain-loop.sh` cloned a repository BEFORE claiming, from a `REPO_URL` fixed in
|
|
5
|
+
* the box's environment at provisioning. That made a per-gig fact a per-box one — the same category
|
|
6
|
+
* error as the `worker_agent` the venue design already removed — and it meant every gig an
|
|
7
|
+
* organization ever dispatched had to work in the same repository.
|
|
8
|
+
*
|
|
9
|
+
* The obvious repair, letting a gig name its own repository through `input_data`, was refused on
|
|
10
|
+
* review and the reasons are worth keeping close to the code:
|
|
11
|
+
*
|
|
12
|
+
* - `input_data` is authored under a gate asking "may this agent RUN this standard". That is not
|
|
13
|
+
* "may it WRITE this repository", and nobody had asked the second question.
|
|
14
|
+
* - `git clone` accepts `ext::sh -c '…'` as a URL. A gig-supplied string is command execution.
|
|
15
|
+
*
|
|
16
|
+
* So the STORE names the repository, on the claim, from a governed column. Nothing the gig carries
|
|
17
|
+
* can influence it, because there is no field in which to carry it.
|
|
18
|
+
*
|
|
19
|
+
* AND THE CREDENTIAL IS FETCHED PER GIG, against a live lease. Not held at boot, not in the
|
|
20
|
+
* container's environment, not the same one twice. A drain between gigs holds no git credential at
|
|
21
|
+
* all — which is the property the per-gig store credential already has, extended to the half that
|
|
22
|
+
* previously sat in a Fly secret for the life of the machine.
|
|
23
|
+
*/
|
|
24
|
+
import { execFileSync } from "node:child_process";
|
|
25
|
+
import { mkdtempSync, rmSync } from "node:fs";
|
|
26
|
+
import { tmpdir } from "node:os";
|
|
27
|
+
import { join } from "node:path";
|
|
28
|
+
/**
|
|
29
|
+
* Trade the venue credential for a git credential scoped to ONE gig's repository.
|
|
30
|
+
*
|
|
31
|
+
* The endpoint decides nothing: it asks the store whether this instance currently holds a live
|
|
32
|
+
* lease on this gig, and mints only for the repository the store names. So a stolen drain key
|
|
33
|
+
* yields nothing here unless the thief is also, right now, doing that gig's work.
|
|
34
|
+
*/
|
|
35
|
+
export async function fetchGitCredential(endpoint, drainKey, instance, gigId) {
|
|
36
|
+
const res = await fetch(endpoint, {
|
|
37
|
+
method: "POST",
|
|
38
|
+
headers: { "content-type": "application/json" },
|
|
39
|
+
body: JSON.stringify({ drain_key: drainKey, instance, gig_id: gigId }),
|
|
40
|
+
});
|
|
41
|
+
const text = await res.text();
|
|
42
|
+
if (!res.ok) {
|
|
43
|
+
let detail = text;
|
|
44
|
+
try {
|
|
45
|
+
detail = JSON.parse(text).error ?? text;
|
|
46
|
+
}
|
|
47
|
+
catch { /* keep the raw body */ }
|
|
48
|
+
throw new Error(`git credential refused (${res.status}): ${detail}`);
|
|
49
|
+
}
|
|
50
|
+
const body = JSON.parse(text);
|
|
51
|
+
if (!body.token)
|
|
52
|
+
throw new Error("git credential endpoint returned no token");
|
|
53
|
+
return { token: body.token, ...(body.expires_at ? { expires_at: body.expires_at } : {}) };
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Shallow-clone `repoUrl` into a fresh temp directory.
|
|
57
|
+
*
|
|
58
|
+
* THE TOKEN NEVER TOUCHES DISK, and that is not incidental. Embedding it in the remote URL
|
|
59
|
+
* (`https://x-access-token:$TOKEN@github.com/…`) writes it verbatim into `.git/config` — inside the
|
|
60
|
+
* very tree the gig's seats then read and write, one `git remote -v` away from model context. A
|
|
61
|
+
* credential helper is consulted only when the server challenges, and reads the token from the
|
|
62
|
+
* helper's own environment at that moment.
|
|
63
|
+
*
|
|
64
|
+
* The helper is supplied through GIT_CONFIG_* rather than `-c`, because `git clone -c k=v` writes k
|
|
65
|
+
* into the NEW clone's .git/config — see the note at the call site. Scoped to `https://github.com`
|
|
66
|
+
* so a URL naming any other host is never offered the token.
|
|
67
|
+
*/
|
|
68
|
+
export function cloneInto(repoUrl, token) {
|
|
69
|
+
const dir = mkdtempSync(join(tmpdir(), "coltrane-gig-"));
|
|
70
|
+
const cleanup = () => {
|
|
71
|
+
try {
|
|
72
|
+
rmSync(dir, { recursive: true, force: true });
|
|
73
|
+
}
|
|
74
|
+
catch { /* a temp dir that will not delete is not worth failing a drained gig over */ }
|
|
75
|
+
};
|
|
76
|
+
const revoke = async () => {
|
|
77
|
+
try {
|
|
78
|
+
await fetch("https://api.github.com/installation/token", {
|
|
79
|
+
method: "DELETE",
|
|
80
|
+
headers: { authorization: `Bearer ${token}`, accept: "application/vnd.github+json" },
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
catch { /* best effort: the token expires on its own within the hour regardless */ }
|
|
84
|
+
};
|
|
85
|
+
try {
|
|
86
|
+
execFileSync("git", ["clone", "--quiet", "--depth", "1", repoUrl, dir], {
|
|
87
|
+
// CONFIG VIA ENVIRONMENT, NOT `-c`. `git clone -c k=v` PERSISTS k into the new clone's
|
|
88
|
+
// .git/config — so a helper passed that way survives into the very tree the gig's seats
|
|
89
|
+
// read. The token itself would not be there, but the helper would, and a later
|
|
90
|
+
// `git push` from a publish seat would consult it, find COLTRANE_GIT_TOKEN unset in that
|
|
91
|
+
// seat's environment, and send an empty password. Caught by a test asserting on the
|
|
92
|
+
// resulting .git/config rather than on the arguments passed.
|
|
93
|
+
//
|
|
94
|
+
// GIT_CONFIG_COUNT applies config to THIS process only and writes nothing to the clone.
|
|
95
|
+
//
|
|
96
|
+
// Scoped to https://github.com so a URL naming any other host is never offered the token.
|
|
97
|
+
// The store constrains repo_url to https and this layer cannot be reached with a
|
|
98
|
+
// gig-supplied string, but a credential helper that answers any host is one refactor away
|
|
99
|
+
// from exfiltration and costs nothing to scope now.
|
|
100
|
+
env: {
|
|
101
|
+
...process.env,
|
|
102
|
+
COLTRANE_GIT_TOKEN: token,
|
|
103
|
+
GIT_CONFIG_COUNT: "1",
|
|
104
|
+
GIT_CONFIG_KEY_0: "credential.https://github.com.helper",
|
|
105
|
+
GIT_CONFIG_VALUE_0: '!f() { echo username=x-access-token; echo "password=$COLTRANE_GIT_TOKEN"; }; f',
|
|
106
|
+
},
|
|
107
|
+
stdio: ["ignore", "ignore", "pipe"],
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
catch (e) {
|
|
111
|
+
cleanup();
|
|
112
|
+
// git writes the useful part to stderr; the message alone is usually just an exit status.
|
|
113
|
+
const stderr = e.stderr?.toString().trim();
|
|
114
|
+
throw new Error(`clone of ${repoUrl} failed${stderr ? `: ${stderr}` : ""}`);
|
|
115
|
+
}
|
|
116
|
+
return { dir, cleanup, revoke };
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Everything above, for one claimed gig — or null when the claim names no repository.
|
|
120
|
+
*
|
|
121
|
+
* NULL IS A NORMAL ANSWER, not a degraded one. An organization that declares no `repo_url` runs
|
|
122
|
+
* gigs that do not touch a working tree, and refusing to run them because a repository is absent
|
|
123
|
+
* would repeat the boot-time refusal this whole change removes. A gig that DOES need a tree will
|
|
124
|
+
* fail on its own terms, naming what it could not find, which is a better error than any this
|
|
125
|
+
* layer could invent.
|
|
126
|
+
*/
|
|
127
|
+
export async function prepareWorkspace(opts) {
|
|
128
|
+
if (!opts.repoUrl)
|
|
129
|
+
return null;
|
|
130
|
+
if (!opts.drainKey || !opts.instance) {
|
|
131
|
+
throw new Error(`the claim named ${opts.repoUrl} but this worker holds no venue credential, so it cannot ` +
|
|
132
|
+
`obtain a git credential for it — set COLTRANE_DRAIN_KEY and COLTRANE_INSTANCE`);
|
|
133
|
+
}
|
|
134
|
+
if (!opts.endpoint) {
|
|
135
|
+
throw new Error(`the claim named ${opts.repoUrl} but COLTRANE_GIT_CREDENTIALS_URL is unset, so there is ` +
|
|
136
|
+
`nowhere to obtain a credential scoped to this gig`);
|
|
137
|
+
}
|
|
138
|
+
const cred = await fetchGitCredential(opts.endpoint, opts.drainKey, opts.instance, opts.gigId);
|
|
139
|
+
return cloneInto(opts.repoUrl, cred.token);
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=workspace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace.js","sourceRoot":"","sources":["../../src/workspace.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eir-labs/coltrane",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.1",
|
|
4
4
|
"description": "A methodology engine — a typed substrate for defining agents, composing multi-phase standards, dispatching gigs, and sealing every output to a content-addressed ledger. Ships as an MCP server.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|