@bradheitmann/odin-sentinel 0.2.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/LICENSE +21 -0
- package/README.md +285 -0
- package/dist/src/bin/index.d.ts +2 -0
- package/dist/src/bin/index.js +17 -0
- package/dist/src/bin/index.js.map +1 -0
- package/dist/src/mcp/server.d.ts +2 -0
- package/dist/src/mcp/server.js +159 -0
- package/dist/src/mcp/server.js.map +1 -0
- package/dist/src/protocol/index.d.ts +2 -0
- package/dist/src/protocol/index.js +2 -0
- package/dist/src/protocol/index.js.map +1 -0
- package/dist/src/protocol/repository.d.ts +16 -0
- package/dist/src/protocol/repository.js +103 -0
- package/dist/src/protocol/repository.js.map +1 -0
- package/dist/src/protocol/schemas.d.ts +64 -0
- package/dist/src/protocol/schemas.js +39 -0
- package/dist/src/protocol/schemas.js.map +1 -0
- package/dist/src/protocol/service.d.ts +52 -0
- package/dist/src/protocol/service.js +322 -0
- package/dist/src/protocol/service.js.map +1 -0
- package/dist/src/protocol/validators.d.ts +16 -0
- package/dist/src/protocol/validators.js +56 -0
- package/dist/src/protocol/validators.js.map +1 -0
- package/dist/src/protocol/version.d.ts +1 -0
- package/dist/src/protocol/version.js +26 -0
- package/dist/src/protocol/version.js.map +1 -0
- package/docs/guides/quick-start.md +74 -0
- package/docs/guides/recommended-starter-team.md +35 -0
- package/docs/reference/client-compatibility.md +59 -0
- package/docs/reference/cost-and-privacy.md +35 -0
- package/docs/reference/distribution.md +74 -0
- package/docs/reference/public-surface-audit.md +133 -0
- package/package.json +69 -0
- package/protocol/SCP.md +34 -0
- package/protocol/closeout.yaml +20 -0
- package/protocol/delegation.yaml +38 -0
- package/protocol/model-profiles.yaml +63 -0
- package/protocol/receipts/boot-receipt.yaml +23 -0
- package/protocol/receipts/team-manifest.yaml +9 -0
- package/protocol/roles.yaml +62 -0
- package/protocol/topology.yaml +22 -0
- package/scripts/audit/public-surface.mjs +67 -0
- package/scripts/audit/verify-pack.mjs +71 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
version: 0.2.1
|
|
2
|
+
roles:
|
|
3
|
+
EXEC_PM:
|
|
4
|
+
title: EXEC PM
|
|
5
|
+
layer: executive
|
|
6
|
+
may_implement_default: false
|
|
7
|
+
may_qa_accept_default: false
|
|
8
|
+
purpose: Intent, priority, authorization, escalation, and claim framing.
|
|
9
|
+
EXEC_ODIN:
|
|
10
|
+
title: EXEC ODIN
|
|
11
|
+
layer: meta_control
|
|
12
|
+
may_implement_default: false
|
|
13
|
+
may_qa_accept_default: false
|
|
14
|
+
purpose: Governance health, polling, delivery proof, role boundaries, and closeout hygiene.
|
|
15
|
+
EXEC_ASST:
|
|
16
|
+
title: EXEC ASST
|
|
17
|
+
layer: executive_support
|
|
18
|
+
may_implement_default: false
|
|
19
|
+
may_qa_accept_default: false
|
|
20
|
+
purpose: Ledger, reminders, pane inventory, artifact index, and delivery checks.
|
|
21
|
+
EXEC_RSCH:
|
|
22
|
+
title: EXEC RSCH
|
|
23
|
+
layer: research
|
|
24
|
+
may_implement_default: false
|
|
25
|
+
may_qa_accept_default: false
|
|
26
|
+
purpose: Read-only strategy, alternatives, context recovery, and risk analysis.
|
|
27
|
+
EXEC_QA:
|
|
28
|
+
title: EXEC QA
|
|
29
|
+
layer: quality
|
|
30
|
+
may_implement_default: false
|
|
31
|
+
may_qa_accept_default: true
|
|
32
|
+
purpose: Independent adversarial audit of process, evidence, closure language, and drift.
|
|
33
|
+
TEAM_PM:
|
|
34
|
+
title: TEAM PM
|
|
35
|
+
layer: pod_control
|
|
36
|
+
may_implement_default: false
|
|
37
|
+
may_qa_accept_default: false
|
|
38
|
+
purpose: Pod task routing, worker activation, and reporting.
|
|
39
|
+
TEAM_ODIN:
|
|
40
|
+
title: TEAM ODIN
|
|
41
|
+
layer: meta_control
|
|
42
|
+
may_implement_default: false
|
|
43
|
+
may_qa_accept_default: false
|
|
44
|
+
purpose: Pod health monitoring, polling, blockers, freezes, and lateral ODIN mesh awareness.
|
|
45
|
+
DEV_WORKER:
|
|
46
|
+
title: DEV WORKER
|
|
47
|
+
layer: implementation
|
|
48
|
+
may_implement_default: true
|
|
49
|
+
may_qa_accept_default: false
|
|
50
|
+
purpose: Bounded implementation inside exact write scope with evidence.
|
|
51
|
+
QA_WORKER:
|
|
52
|
+
title: QA WORKER
|
|
53
|
+
layer: quality
|
|
54
|
+
may_implement_default: false
|
|
55
|
+
may_qa_accept_default: true
|
|
56
|
+
purpose: Independent verification of worker evidence and acceptance criteria.
|
|
57
|
+
SHADOW_REVIEWER:
|
|
58
|
+
title: SHADOW REVIEWER
|
|
59
|
+
layer: review
|
|
60
|
+
may_implement_default: false
|
|
61
|
+
may_qa_accept_default: false
|
|
62
|
+
purpose: Independent critique, risk surfacing, and second-pass review.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
version: 0.2.1
|
|
2
|
+
default_topology:
|
|
3
|
+
executive_office:
|
|
4
|
+
team: A
|
|
5
|
+
slots:
|
|
6
|
+
- A/EXEC-PM
|
|
7
|
+
- A/EXEC-ODIN
|
|
8
|
+
- A/EXEC-ASST
|
|
9
|
+
- A/EXEC-RSCH
|
|
10
|
+
- A/EXEC-QA
|
|
11
|
+
development_pod:
|
|
12
|
+
slots:
|
|
13
|
+
- "{TEAM}/TEAM-PM"
|
|
14
|
+
- "{TEAM}/ODIN"
|
|
15
|
+
- "{TEAM}/DEV-1"
|
|
16
|
+
- "{TEAM}/QA-1"
|
|
17
|
+
- "{TEAM}/SHADOW-1"
|
|
18
|
+
fresh_repo_default_pods: 1
|
|
19
|
+
odin_mesh:
|
|
20
|
+
bootstrap_identity_exchange: true
|
|
21
|
+
health_round_robin_minutes: 10
|
|
22
|
+
aggregator: A/EXEC-ODIN
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { execFileSync } from "node:child_process";
|
|
2
|
+
import { readdirSync, readFileSync, statSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
|
|
5
|
+
function walk(dir) {
|
|
6
|
+
return readdirSync(dir).flatMap((entry) => {
|
|
7
|
+
const path = join(dir, entry);
|
|
8
|
+
if ([".git", "dist", "node_modules"].includes(entry)) return [];
|
|
9
|
+
if (path === "pnpm-lock.yaml") return [];
|
|
10
|
+
return statSync(path).isDirectory() ? walk(path) : [path];
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function filesToAudit() {
|
|
15
|
+
try {
|
|
16
|
+
const tracked = execFileSync("git", ["ls-files"], {
|
|
17
|
+
encoding: "utf8",
|
|
18
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
19
|
+
});
|
|
20
|
+
const untracked = execFileSync("git", ["ls-files", "--others", "--exclude-standard"], {
|
|
21
|
+
encoding: "utf8",
|
|
22
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
return `${tracked}\n${untracked}`
|
|
26
|
+
.split("\n")
|
|
27
|
+
.filter(Boolean)
|
|
28
|
+
.filter((file) => !file.startsWith("pnpm-lock.yaml"));
|
|
29
|
+
} catch {
|
|
30
|
+
return walk(".");
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const publicFiles = filesToAudit();
|
|
35
|
+
|
|
36
|
+
const forbidden = [
|
|
37
|
+
{ name: "macOS home path", pattern: new RegExp(`/${"Users"}/[A-Za-z0-9._-]+/`) },
|
|
38
|
+
{ name: "Linux home path", pattern: /\/home\/[A-Za-z0-9._-]+\// },
|
|
39
|
+
{ name: "tilde home path", pattern: /~\// },
|
|
40
|
+
{ name: "local agent config path", pattern: new RegExp(`\\.${"codex"}|\\.${"claude"}|\\.${"agents"}`, "i") },
|
|
41
|
+
{ name: "legacy extension terminology", pattern: new RegExp(`\\b${"sk" + "ill"}\\b|${"SK" + "ILL"}\\.md|export_${"sk" + "ill"}_snapshot`, "i") },
|
|
42
|
+
{
|
|
43
|
+
name: "private project or account marker",
|
|
44
|
+
pattern: new RegExp(
|
|
45
|
+
`\\b(edge-${"agentic"}|Edu${"gentic"}|${"OK" + "OA"}|open_${"protocols"})\\b`,
|
|
46
|
+
"i"
|
|
47
|
+
)
|
|
48
|
+
},
|
|
49
|
+
{ name: "secret-looking assignment", pattern: /(api[_-]?key|secret|token|password)\s*[:=]\s*["'][^"']+["']/i }
|
|
50
|
+
];
|
|
51
|
+
|
|
52
|
+
const findings = [];
|
|
53
|
+
|
|
54
|
+
for (const file of publicFiles) {
|
|
55
|
+
const text = readFileSync(file, "utf8");
|
|
56
|
+
for (const rule of forbidden) {
|
|
57
|
+
if (rule.pattern.test(text)) {
|
|
58
|
+
findings.push(`${file}: ${rule.name}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (findings.length > 0) {
|
|
64
|
+
throw new Error(`Public surface audit failed:\n${findings.join("\n")}`);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
console.log(`Public surface audit PASS: ${publicFiles.length} files checked`);
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { execFileSync } from "node:child_process";
|
|
2
|
+
|
|
3
|
+
const output = execFileSync("pnpm", ["pack", "--dry-run", "--json"], {
|
|
4
|
+
encoding: "utf8",
|
|
5
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
// pnpm 11 writes JSON directly to stdout (no preamble); pnpm <=10 prefixed
|
|
9
|
+
// it with lifecycle logs. Handle both shapes: take from "\n{" if present, or
|
|
10
|
+
// from the start if output already begins with "{".
|
|
11
|
+
const newlineBrace = output.lastIndexOf("\n{");
|
|
12
|
+
const jsonStart = newlineBrace !== -1 ? newlineBrace + 1 : (output.trimStart().startsWith("{") ? output.indexOf("{") : -1);
|
|
13
|
+
if (jsonStart === -1) {
|
|
14
|
+
throw new Error("pnpm pack did not return JSON metadata");
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const pack = JSON.parse(output.slice(jsonStart));
|
|
18
|
+
const paths = new Set(pack.files.map((file) => file.path));
|
|
19
|
+
|
|
20
|
+
const requiredProtocolFiles = [
|
|
21
|
+
"protocol/SCP.md",
|
|
22
|
+
"protocol/roles.yaml",
|
|
23
|
+
"protocol/topology.yaml",
|
|
24
|
+
"protocol/model-profiles.yaml",
|
|
25
|
+
"protocol/closeout.yaml",
|
|
26
|
+
"protocol/delegation.yaml",
|
|
27
|
+
"protocol/receipts/boot-receipt.yaml",
|
|
28
|
+
"protocol/receipts/team-manifest.yaml"
|
|
29
|
+
];
|
|
30
|
+
|
|
31
|
+
const requiredFiles = [
|
|
32
|
+
"dist/src/bin/index.js",
|
|
33
|
+
"dist/src/mcp/server.js",
|
|
34
|
+
"dist/src/protocol/index.js",
|
|
35
|
+
"dist/src/protocol/service.js",
|
|
36
|
+
"dist/src/protocol/repository.js",
|
|
37
|
+
"dist/src/protocol/schemas.js",
|
|
38
|
+
"dist/src/protocol/validators.js",
|
|
39
|
+
"dist/src/protocol/version.js",
|
|
40
|
+
"docs/guides/quick-start.md",
|
|
41
|
+
"docs/guides/recommended-starter-team.md",
|
|
42
|
+
"docs/reference/client-compatibility.md",
|
|
43
|
+
"docs/reference/cost-and-privacy.md",
|
|
44
|
+
"docs/reference/distribution.md",
|
|
45
|
+
"docs/reference/public-surface-audit.md",
|
|
46
|
+
...requiredProtocolFiles,
|
|
47
|
+
"scripts/audit/public-surface.mjs",
|
|
48
|
+
"scripts/audit/verify-pack.mjs",
|
|
49
|
+
"README.md",
|
|
50
|
+
"LICENSE",
|
|
51
|
+
"package.json"
|
|
52
|
+
];
|
|
53
|
+
|
|
54
|
+
const missing = requiredFiles.filter((file) => !paths.has(file));
|
|
55
|
+
if (missing.length > 0) {
|
|
56
|
+
throw new Error(`Package is missing required files: ${missing.join(", ")}`);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const staleFiles = [
|
|
60
|
+
"dist/src/index.js",
|
|
61
|
+
"dist/src/server.js",
|
|
62
|
+
"dist/src/protocol.js",
|
|
63
|
+
"dist/src/protocol-repository.js",
|
|
64
|
+
"dist/src/validators.js"
|
|
65
|
+
].filter((file) => paths.has(file));
|
|
66
|
+
|
|
67
|
+
if (staleFiles.length > 0) {
|
|
68
|
+
throw new Error(`Package includes stale build files: ${staleFiles.join(", ")}`);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
console.log(`Package smoke PASS: ${pack.files.length} files included in ${pack.filename}`);
|