hub-evaluator-may-approve.mjs
60 lines 2.0 KB
Raw
sha256:65ccb454656ea5acdea0a10e559b78bcde1eb6ff753ecc2911bc99d1c3d7cadd feat(calendar): enforce agent context tiers in retrieval AP… Human minor ⚠ breaking 2 days ago
1 /**
2 * Per-user "evaluator may approve" map (self-hosted Hub data dir).
3 * Hosted uses bridge blob `hub_evaluator_may_approve`; same JSON shape: { evaluator_may_approve: { "sub": true, ... } }.
4 */
5
6 import fs from 'fs';
7 import path from 'path';
8
9 const FILE = 'hub_evaluator_may_approve.json';
10
11 /**
12 * @param {string} dataDir
13 * @returns {Record<string, boolean>}
14 */
15 export function readEvaluatorMayApprove(dataDir) {
16 if (!dataDir) return {};
17 const filePath = path.join(dataDir, FILE);
18 try {
19 if (!fs.existsSync(filePath)) return {};
20 const data = JSON.parse(fs.readFileSync(filePath, 'utf8'));
21 const m = data?.evaluator_may_approve != null ? data.evaluator_may_approve : data;
22 if (typeof m !== 'object' || m === null) return {};
23 const out = {};
24 for (const [k, v] of Object.entries(m)) {
25 if (typeof k === 'string' && k.trim()) out[k.trim()] = Boolean(v);
26 }
27 return out;
28 } catch {
29 return {};
30 }
31 }
32
33 /**
34 * @param {string} dataDir
35 * @param {Record<string, boolean>} map
36 */
37 export function writeEvaluatorMayApprove(dataDir, map) {
38 if (!dataDir) throw new Error('data_dir required');
39 const filePath = path.join(dataDir, FILE);
40 const obj = {};
41 for (const [k, v] of Object.entries(map)) {
42 if (typeof k === 'string' && k.trim()) obj[k.trim()] = Boolean(v);
43 }
44 fs.mkdirSync(dataDir, { recursive: true });
45 fs.writeFileSync(filePath, JSON.stringify({ evaluator_may_approve: obj }, null, 2), 'utf8');
46 }
47
48 /**
49 * Whether the actor may approve proposals (admin always; evaluator from map + env fallback).
50 * @param {string} sub
51 * @param {string} role - effective role (admin, editor, viewer, evaluator, member)
52 * @param {Record<string, boolean>} mayMap
53 * @param {boolean} envFallback - HUB_EVALUATOR_MAY_APPROVE === '1'
54 */
55 export function actorMayApproveProposals(sub, role, mayMap, envFallback) {
56 if (role === 'admin') return true;
57 if (role !== 'evaluator') return false;
58 if (Object.prototype.hasOwnProperty.call(mayMap, sub)) return Boolean(mayMap[sub]);
59 return envFallback;
60 }
File History 2 commits
sha256:65ccb454656ea5acdea0a10e559b78bcde1eb6ff753ecc2911bc99d1c3d7cadd feat(calendar): enforce agent context tiers in retrieval AP… Human minor 2 days ago
sha256:9103f98c89257ed2b01c237cea895dabb3e85ea337dccb1161c175e4422355b6 docs: accept Calendar Events v0 spec with Phase 0 security … Human 2 days ago