@occasiolabs/occasio 0.8.2 → 0.8.3
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/NOTICE +4 -4
- package/bin/supervisor/README.md +2 -2
- package/bin/supervisor/com.occasio.proxy.plist.template +3 -3
- package/bin/supervisor/install-windows-task.ps1 +7 -7
- package/bin/supervisor/occasio.service +1 -1
- package/package.json +1 -1
- package/src/harness.js +6 -6
- package/src/index.js +2 -2
- package/src/mcp-server.js +1 -1
- package/src/policy/loader.js +2 -2
- package/src/redteam.js +1 -1
- package/docs/__pycache__/audit_walker.cpython-313.pyc +0 -0
- package/docs/__pycache__/canonicalize.cpython-313.pyc +0 -0
package/NOTICE
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
Occasio
|
|
2
2
|
Copyright 2026 Leonard Brauer
|
|
3
3
|
|
|
4
|
-
This product includes software developed by the
|
|
5
|
-
(https://github.com/
|
|
4
|
+
This product includes software developed by the Occasio project
|
|
5
|
+
(https://github.com/occasiolabs/occasio).
|
|
6
6
|
|
|
7
7
|
Licensed under the Apache License, Version 2.0 (see LICENSE).
|
|
8
8
|
|
|
9
|
-
Versions 0.6.6 and earlier of
|
|
9
|
+
Versions 0.6.6 and earlier of Occasio were released under the MIT License
|
|
10
10
|
and remain available under MIT in perpetuity for those releases.
|
package/bin/supervisor/README.md
CHANGED
|
@@ -38,12 +38,12 @@ rm ~/.config/systemd/user/occasio.service
|
|
|
38
38
|
|
|
39
39
|
## macOS (launchd, user scope)
|
|
40
40
|
|
|
41
|
-
The plist is a template: replace `{{
|
|
41
|
+
The plist is a template: replace `{{OCCASIO_BIN}}` with the absolute
|
|
42
42
|
path to your `occasio` binary first.
|
|
43
43
|
|
|
44
44
|
```sh
|
|
45
45
|
LF_BIN="$(command -v occasio)"
|
|
46
|
-
sed "s|{{
|
|
46
|
+
sed "s|{{OCCASIO_BIN}}|$LF_BIN|g" com.occasio.proxy.plist.template \
|
|
47
47
|
> ~/Library/LaunchAgents/ai.occasio.proxy.plist
|
|
48
48
|
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/ai.occasio.proxy.plist
|
|
49
49
|
launchctl print gui/$(id -u)/ai.occasio.proxy
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
2
|
<!--
|
|
3
|
-
|
|
3
|
+
Occasio launchd template (v0.6.4).
|
|
4
4
|
|
|
5
|
-
This file is a TEMPLATE: replace {{
|
|
5
|
+
This file is a TEMPLATE: replace {{OCCASIO_BIN}} with the absolute
|
|
6
6
|
path to your `occasio` executable before installing. See
|
|
7
7
|
bin/supervisor/README.md for the install command.
|
|
8
8
|
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
|
|
19
19
|
<key>ProgramArguments</key>
|
|
20
20
|
<array>
|
|
21
|
-
<string>{{
|
|
21
|
+
<string>{{OCCASIO_BIN}}</string>
|
|
22
22
|
<string>start</string>
|
|
23
23
|
</array>
|
|
24
24
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
the current user, restarting it within 30 seconds if it exits.
|
|
5
5
|
|
|
6
6
|
.DESCRIPTION
|
|
7
|
-
v0.6.4 of
|
|
7
|
+
v0.6.4 of Occasio aborts with exit code 1 when it cannot append to
|
|
8
8
|
its audit log. This task brings the proxy back up so the agent can
|
|
9
9
|
resume work as soon as the underlying I/O issue clears.
|
|
10
10
|
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
Manually validated on Windows 11 Pro (PowerShell 7.x).
|
|
13
13
|
Tested-on: Windows.
|
|
14
14
|
|
|
15
|
-
The task runs at user logon, not at boot, because
|
|
15
|
+
The task runs at user logon, not at boot, because Occasio's audit
|
|
16
16
|
log lives in the user profile (~/.occasio/). Run from an elevated
|
|
17
17
|
shell only if you need the task to survive logoff.
|
|
18
18
|
#>
|
|
@@ -35,14 +35,14 @@ $Principal = New-ScheduledTaskPrincipal `
|
|
|
35
35
|
-RunLevel Limited
|
|
36
36
|
|
|
37
37
|
Register-ScheduledTask `
|
|
38
|
-
-TaskName "
|
|
39
|
-
-Description "
|
|
38
|
+
-TaskName "Occasio" `
|
|
39
|
+
-Description "Occasio — local AI-agent governance proxy (v0.6.4)" `
|
|
40
40
|
-Action $Action `
|
|
41
41
|
-Trigger $Trigger `
|
|
42
42
|
-Settings $Settings `
|
|
43
43
|
-Principal $Principal `
|
|
44
44
|
-Force
|
|
45
45
|
|
|
46
|
-
Write-Host "Registered scheduled task '
|
|
47
|
-
Write-Host "It will start at next logon. To start now: Start-ScheduledTask -TaskName
|
|
48
|
-
Write-Host "To remove: Unregister-ScheduledTask -TaskName
|
|
46
|
+
Write-Host "Registered scheduled task 'Occasio'."
|
|
47
|
+
Write-Host "It will start at next logon. To start now: Start-ScheduledTask -TaskName Occasio"
|
|
48
|
+
Write-Host "To remove: Unregister-ScheduledTask -TaskName Occasio -Confirm:`$false"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@occasiolabs/occasio",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.3",
|
|
4
4
|
"description": "Occasio — cryptographically verifiable behavioral attestation for AI coding agents. Tool-call interception + policy enforcement + tamper-evident audit chain + Sigstore-signed in-toto attestations + windowed EDR detection. Same engine for Claude Code and MCP; Computer-Use scaffold included.",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"files": [
|
package/src/harness.js
CHANGED
|
@@ -538,9 +538,9 @@ function runScenarioChild(scenarioName, ctx, opts = {}) {
|
|
|
538
538
|
|
|
539
539
|
const env = {
|
|
540
540
|
...process.env,
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
541
|
+
OCCASIO_PORT: String(port),
|
|
542
|
+
OCCASIO_AUDIT_FILE: ctx.auditPath,
|
|
543
|
+
OCCASIO_POLICY_FILE: ctx.policyPath,
|
|
544
544
|
};
|
|
545
545
|
// Only set ANTHROPIC_API_KEY if we actually have one. Empty/undefined
|
|
546
546
|
// would override the user's Claude Code bundled auth, which is the
|
|
@@ -598,8 +598,8 @@ function runMcpScenario(scenarioName, ctx, opts = {}) {
|
|
|
598
598
|
return new Promise((resolve) => {
|
|
599
599
|
const env = {
|
|
600
600
|
...process.env,
|
|
601
|
-
|
|
602
|
-
|
|
601
|
+
OCCASIO_AUDIT_FILE: ctx.auditPath,
|
|
602
|
+
OCCASIO_POLICY_FILE: ctx.policyPath,
|
|
603
603
|
};
|
|
604
604
|
const child = spawnFn('node', [mcpBin], {
|
|
605
605
|
cwd: ctx.workspace, env, stdio: ['pipe', 'pipe', 'pipe'],
|
|
@@ -749,7 +749,7 @@ async function runHarness(opts = {}) {
|
|
|
749
749
|
v.workspace = ctx.workspace;
|
|
750
750
|
results.push(v);
|
|
751
751
|
} finally {
|
|
752
|
-
if (!opts.keepScratch && !process.env.
|
|
752
|
+
if (!opts.keepScratch && !process.env.OCC_HARNESS_KEEP) {
|
|
753
753
|
cleanupWorkspace(ctx);
|
|
754
754
|
}
|
|
755
755
|
}
|
package/src/index.js
CHANGED
|
@@ -59,7 +59,7 @@ const LOG_SCHEMA_VERSION = 2;
|
|
|
59
59
|
// Port override via env var (used by `occasio harness` and redteam to
|
|
60
60
|
// run isolated proxies against scratch audit chains on free ports). Default
|
|
61
61
|
// is 8081 to preserve existing user-facing behaviour.
|
|
62
|
-
let PORT = parseInt(process.env.
|
|
62
|
+
let PORT = parseInt(process.env.OCCASIO_PORT, 10) || 8081;
|
|
63
63
|
const ANTHROPIC_REAL = 'api.anthropic.com';
|
|
64
64
|
const LOG_DIR = path.join(os.homedir(), '.occasio');
|
|
65
65
|
const SESSION_FILE = path.join(LOG_DIR, 'session.json');
|
|
@@ -926,7 +926,7 @@ const { createAuditor: _createAuditor } = require('./audit/jsonl-auditor');
|
|
|
926
926
|
// Audit-file override via env var. Used by `occasio harness` to run
|
|
927
927
|
// against a scratch chain so the user's real ~/.occasio/pipeline-events
|
|
928
928
|
// .jsonl is never touched. When unset, the auditor uses its default location.
|
|
929
|
-
const sessionAuditor = _createAuditor(process.env.
|
|
929
|
+
const sessionAuditor = _createAuditor(process.env.OCCASIO_AUDIT_FILE || undefined);
|
|
930
930
|
|
|
931
931
|
// v0.6.6: register a policy-change listener that emits a `policy_loaded`
|
|
932
932
|
// audit row whenever the active policy hash transitions to a new value
|
package/src/mcp-server.js
CHANGED
|
@@ -44,7 +44,7 @@ const LOG_FILE = path.join(os.homedir(), '.occasio', 'mcp-experiment.jsonl');
|
|
|
44
44
|
// Audit-file override via env var (symmetric with the Claude Code proxy
|
|
45
45
|
// in src/index.js). Used by `occasio harness --scenario mcp-*` to
|
|
46
46
|
// keep MCP test traffic out of the user's real ~/.occasio chain.
|
|
47
|
-
let mcpAuditor = createAuditor(process.env.
|
|
47
|
+
let mcpAuditor = createAuditor(process.env.OCCASIO_AUDIT_FILE || undefined);
|
|
48
48
|
|
|
49
49
|
// v0.6.6: emit a policy_loaded row on first policy load and on every
|
|
50
50
|
// hot-reload that changes the policy file's bytes. The MCP server is a
|
package/src/policy/loader.js
CHANGED
|
@@ -26,10 +26,10 @@ function resolveConfigPath(p) {
|
|
|
26
26
|
return path.resolve(expanded);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
// Default path can be overridden via
|
|
29
|
+
// Default path can be overridden via OCCASIO_POLICY_FILE — used by the
|
|
30
30
|
// harness/redteam commands to point the proxy at a scratch policy.yml so
|
|
31
31
|
// the user's real ~/.occasio/policy.yml is never read.
|
|
32
|
-
const DEFAULT_PATH = process.env.
|
|
32
|
+
const DEFAULT_PATH = process.env.OCCASIO_POLICY_FILE
|
|
33
33
|
|| path.join(os.homedir(), '.occasio', 'policy.yml');
|
|
34
34
|
|
|
35
35
|
// Default tool routing matches the pre-Stage-3 hardcoded behavior.
|
package/src/redteam.js
CHANGED
|
@@ -410,7 +410,7 @@ async function runRedteamCli(args = []) {
|
|
|
410
410
|
process.stdout.write('\n');
|
|
411
411
|
return result;
|
|
412
412
|
} finally {
|
|
413
|
-
if (!keepScratch && !process.env.
|
|
413
|
+
if (!keepScratch && !process.env.OCC_REDTEAM_KEEP) {
|
|
414
414
|
try { fs.rmSync(ctx.workspace, { recursive: true, force: true }); } catch {}
|
|
415
415
|
}
|
|
416
416
|
}
|
|
Binary file
|
|
Binary file
|