instar 0.28.52 → 0.28.53
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/cli.js +40 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/gate.d.ts +33 -0
- package/dist/commands/gate.d.ts.map +1 -0
- package/dist/commands/gate.js +171 -0
- package/dist/commands/gate.js.map +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +29 -2
- package/dist/commands/init.js.map +1 -1
- package/dist/core/MessageSentinel.d.ts +40 -0
- package/dist/core/MessageSentinel.d.ts.map +1 -1
- package/dist/core/MessageSentinel.js +80 -0
- package/dist/core/MessageSentinel.js.map +1 -1
- package/dist/core/PostUpdateMigrator.d.ts +7 -0
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +114 -0
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/core/SessionManager.d.ts +29 -0
- package/dist/core/SessionManager.d.ts.map +1 -1
- package/dist/core/SessionManager.js +104 -1
- package/dist/core/SessionManager.js.map +1 -1
- package/dist/core/StopGateDb.d.ts +97 -0
- package/dist/core/StopGateDb.d.ts.map +1 -0
- package/dist/core/StopGateDb.js +282 -0
- package/dist/core/StopGateDb.js.map +1 -0
- package/dist/core/UnjustifiedStopGate.d.ts +145 -0
- package/dist/core/UnjustifiedStopGate.d.ts.map +1 -0
- package/dist/core/UnjustifiedStopGate.js +325 -0
- package/dist/core/UnjustifiedStopGate.js.map +1 -0
- package/dist/core/WorktreeKeyVault.d.ts +50 -0
- package/dist/core/WorktreeKeyVault.d.ts.map +1 -0
- package/dist/core/WorktreeKeyVault.js +242 -0
- package/dist/core/WorktreeKeyVault.js.map +1 -0
- package/dist/core/WorktreeManager.d.ts +250 -0
- package/dist/core/WorktreeManager.d.ts.map +1 -0
- package/dist/core/WorktreeManager.js +833 -0
- package/dist/core/WorktreeManager.js.map +1 -0
- package/dist/monitoring/DegradationReporter.d.ts +15 -0
- package/dist/monitoring/DegradationReporter.d.ts.map +1 -1
- package/dist/monitoring/DegradationReporter.js +27 -0
- package/dist/monitoring/DegradationReporter.js.map +1 -1
- package/dist/monitoring/WorktreeReaper.d.ts +52 -0
- package/dist/monitoring/WorktreeReaper.d.ts.map +1 -0
- package/dist/monitoring/WorktreeReaper.js +199 -0
- package/dist/monitoring/WorktreeReaper.js.map +1 -0
- package/dist/scaffold/templates.d.ts.map +1 -1
- package/dist/scaffold/templates.js +8 -0
- package/dist/scaffold/templates.js.map +1 -1
- package/dist/server/AgentServer.d.ts +18 -0
- package/dist/server/AgentServer.d.ts.map +1 -1
- package/dist/server/AgentServer.js +24 -0
- package/dist/server/AgentServer.js.map +1 -1
- package/dist/server/middleware.d.ts.map +1 -1
- package/dist/server/middleware.js +20 -3
- package/dist/server/middleware.js.map +1 -1
- package/dist/server/routes.d.ts +10 -0
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +432 -0
- package/dist/server/routes.js.map +1 -1
- package/dist/server/stopGate.d.ts +77 -0
- package/dist/server/stopGate.d.ts.map +1 -0
- package/dist/server/stopGate.js +161 -0
- package/dist/server/stopGate.js.map +1 -0
- package/dist/server/worktreeRoutes.d.ts +48 -0
- package/dist/server/worktreeRoutes.d.ts.map +1 -0
- package/dist/server/worktreeRoutes.js +247 -0
- package/dist/server/worktreeRoutes.js.map +1 -0
- package/package.json +1 -1
- package/scripts/destructive-command-shim.js +218 -0
- package/scripts/gh-ruleset-install.mjs +143 -0
- package/scripts/migrate-incident-2026-04-17.mjs +138 -0
- package/scripts/worktree-commit-msg-hook.js +168 -0
- package/scripts/worktree-precommit-gate.js +144 -0
- package/src/data/builtin-manifest.json +93 -93
- package/upgrades/0.28.53.md +70 -0
- package/upgrades/side-effects/context-death-pr0a-server-infra.md +131 -0
- package/upgrades/side-effects/context-death-pr0b-sentinel-intent.md +130 -0
- package/upgrades/side-effects/context-death-pr0c-guardian-pulse-degradation-consumer.md +118 -0
- package/upgrades/side-effects/context-death-pr0d-e2e-compaction-harness.md +113 -0
- package/upgrades/side-effects/context-death-pr1-identity-text.md +110 -0
- package/upgrades/side-effects/context-death-pr2-e2e-compaction-recovery-test.md +82 -0
- package/upgrades/side-effects/context-death-pr3-gate-authority.md +193 -0
- package/upgrades/side-effects/context-death-pr4-gate-cli.md +91 -0
- package/upgrades/side-effects/parallel-dev-isolation.md +129 -0
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* worktree-precommit-gate.js — pre-commit gate for parallel-dev isolation.
|
|
4
|
+
*
|
|
5
|
+
* Ensures the cwd of this commit matches the worktree the active session was
|
|
6
|
+
* granted, and that the session's fencing token is still current. Calls the
|
|
7
|
+
* agent server's POST /commits/preflight; fail-open-to-warn on timeout.
|
|
8
|
+
*
|
|
9
|
+
* Exit codes:
|
|
10
|
+
* 0 — pass (binding+lock OK, or warn on timeout)
|
|
11
|
+
* 1 — block (cwd-not-in-binding, fencing-token-mismatch, read-only mode, etc.)
|
|
12
|
+
*
|
|
13
|
+
* Reads INSTAR_SERVER_URL + INSTAR_AUTH_TOKEN from env (set by SessionManager).
|
|
14
|
+
* Reads .instar/session-context.json for sessionId + fencingToken.
|
|
15
|
+
*
|
|
16
|
+
* Per spec section: "Pre-commit fence (advisory layer, iter 3)".
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import fs from 'node:fs';
|
|
20
|
+
import http from 'node:http';
|
|
21
|
+
import path from 'node:path';
|
|
22
|
+
import { execSync } from 'node:child_process';
|
|
23
|
+
|
|
24
|
+
const PREFLIGHT_TIMEOUT_MS = 500;
|
|
25
|
+
|
|
26
|
+
function findSessionContext(startCwd) {
|
|
27
|
+
let cwd = startCwd;
|
|
28
|
+
for (let i = 0; i < 10; i++) {
|
|
29
|
+
const ctx = path.join(cwd, '.instar', 'session-context.json');
|
|
30
|
+
if (fs.existsSync(ctx)) return ctx;
|
|
31
|
+
const parent = path.dirname(cwd);
|
|
32
|
+
if (parent === cwd) break;
|
|
33
|
+
cwd = parent;
|
|
34
|
+
}
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function readContext(ctxPath) {
|
|
39
|
+
try { return JSON.parse(fs.readFileSync(ctxPath, 'utf-8')); }
|
|
40
|
+
catch { return null; }
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function postPreflight({ serverUrl, authToken, cwd, fencingToken, stagedFiles }) {
|
|
44
|
+
return new Promise((resolve) => {
|
|
45
|
+
const url = new URL(serverUrl);
|
|
46
|
+
const body = JSON.stringify({ cwd, fencingToken, stagedFiles });
|
|
47
|
+
const req = http.request({
|
|
48
|
+
method: 'POST',
|
|
49
|
+
hostname: url.hostname,
|
|
50
|
+
port: url.port,
|
|
51
|
+
path: '/commits/preflight',
|
|
52
|
+
headers: {
|
|
53
|
+
'Content-Type': 'application/json',
|
|
54
|
+
'Content-Length': Buffer.byteLength(body),
|
|
55
|
+
'Authorization': `Bearer ${authToken}`,
|
|
56
|
+
},
|
|
57
|
+
timeout: PREFLIGHT_TIMEOUT_MS,
|
|
58
|
+
}, (res) => {
|
|
59
|
+
let data = '';
|
|
60
|
+
res.on('data', (c) => data += c);
|
|
61
|
+
res.on('end', () => {
|
|
62
|
+
try { resolve({ ok: true, status: res.statusCode, body: JSON.parse(data) }); }
|
|
63
|
+
catch { resolve({ ok: false, reason: 'invalid-json' }); }
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
req.on('timeout', () => { req.destroy(); resolve({ ok: false, reason: 'timeout' }); });
|
|
67
|
+
req.on('error', (err) => resolve({ ok: false, reason: err.code || err.message }));
|
|
68
|
+
req.write(body);
|
|
69
|
+
req.end();
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async function main() {
|
|
74
|
+
const cwd = process.cwd();
|
|
75
|
+
const ctxPath = findSessionContext(cwd);
|
|
76
|
+
if (!ctxPath) {
|
|
77
|
+
// No session context — likely a manual commit by the user, not an agent. Pass.
|
|
78
|
+
process.exit(0);
|
|
79
|
+
}
|
|
80
|
+
const ctx = readContext(ctxPath);
|
|
81
|
+
if (!ctx || !ctx.sessionId || !ctx.fencingToken) {
|
|
82
|
+
console.error('worktree-precommit: malformed session-context.json — skipping gate');
|
|
83
|
+
process.exit(0);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (ctx.mode === 'read-only') {
|
|
87
|
+
console.error('worktree-precommit: BLOCK — this is a read-only worktree. Use /promote-to-dev to convert, or /quick-doc-fix.');
|
|
88
|
+
process.exit(1);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Check fail-open env (only honored for warn mode)
|
|
92
|
+
const isolationMode = process.env.INSTAR_PARALLEL_ISOLATION ?? 'block';
|
|
93
|
+
|
|
94
|
+
// Collect staged files (from `git diff --cached --name-only`)
|
|
95
|
+
let stagedFiles = [];
|
|
96
|
+
try {
|
|
97
|
+
stagedFiles = execSync('git diff --cached --name-only -z', { encoding: 'utf-8', cwd })
|
|
98
|
+
.split('\0').filter(Boolean);
|
|
99
|
+
} catch { /* @silent-fallback-ok */ }
|
|
100
|
+
|
|
101
|
+
const serverUrl = process.env.INSTAR_SERVER_URL;
|
|
102
|
+
const authToken = process.env.INSTAR_AUTH_TOKEN;
|
|
103
|
+
if (!serverUrl || !authToken) {
|
|
104
|
+
console.error('worktree-precommit: WARN — missing INSTAR_SERVER_URL/INSTAR_AUTH_TOKEN; cannot enforce. Continuing.');
|
|
105
|
+
process.exit(0);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const result = await postPreflight({
|
|
109
|
+
serverUrl,
|
|
110
|
+
authToken,
|
|
111
|
+
cwd,
|
|
112
|
+
fencingToken: ctx.fencingToken,
|
|
113
|
+
stagedFiles,
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
if (!result.ok || result.reason === 'timeout') {
|
|
117
|
+
console.error(`worktree-precommit: WARN — preflight ${result.reason ?? 'failed'}; failing open (warn mode).`);
|
|
118
|
+
process.exit(0);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (result.body && result.body.ok === true) {
|
|
122
|
+
process.exit(0);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const code = result.body?.code ?? 'unknown';
|
|
126
|
+
const message = result.body?.message ?? 'preflight rejected';
|
|
127
|
+
|
|
128
|
+
if (isolationMode === 'warn') {
|
|
129
|
+
console.error(`worktree-precommit: WARN [${code}] ${message} (would BLOCK in enforcing mode)`);
|
|
130
|
+
process.exit(0);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
console.error(`worktree-precommit: BLOCK [${code}] ${message}`);
|
|
134
|
+
console.error(` → cwd: ${cwd}`);
|
|
135
|
+
console.error(` → session-context: ${ctxPath}`);
|
|
136
|
+
console.error(' → If this is wrong, run: instar worktree status');
|
|
137
|
+
process.exit(1);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
main().catch((err) => {
|
|
141
|
+
console.error(`worktree-precommit: ERROR ${err.message}`);
|
|
142
|
+
// Fail-open on uncaught errors (matches timeout behavior)
|
|
143
|
+
process.exit(0);
|
|
144
|
+
});
|