@cstack-protocol/pingala 1.0.0
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/.agent/CSD.md +39 -0
- package/.agent/MANIFEST.md +4 -0
- package/.agent/MANIFEST.md.template +4 -0
- package/.agent/agent-contractor.md +45 -0
- package/.agent/architecture/consent-model-fsm.md +77 -0
- package/.agent/architecture/governor-maturity-fsm.md +101 -0
- package/.agent/architecture/governor-validation-fsm.md +106 -0
- package/.agent/architecture/humanized-audit-fsm.md +76 -0
- package/.agent/architecture/pingala-csi-fsm.md +81 -0
- package/.agent/architecture.md +34 -0
- package/.agent/behavior.md +29 -0
- package/.agent/compute.md +32 -0
- package/.agent/consent-prompts.md +41 -0
- package/.agent/governance.yaml +5 -0
- package/.agent/identity.md +29 -0
- package/.agent/knowledge-lattice.json +96 -0
- package/.agent/knowledge-lattice.md +53 -0
- package/.agent/lattice-viz.html +157 -0
- package/.agent/mission.md +37 -0
- package/.agent/pairing-protocol.md +89 -0
- package/.agent/pairing.csp +108 -0
- package/.agent/personas/reflective-operator.md +67 -0
- package/.agent/personas/research.md +62 -0
- package/.agent/pingala.md +47 -0
- package/.agent/roadmap.md +56 -0
- package/.agent/scripts/lattice-extract.py +100 -0
- package/.agent/scripts/sync-agents.sh +82 -0
- package/.agent/scripts/vault-ingest.py +80 -0
- package/.agent/seo-strategy.md +71 -0
- package/.agent/skills/agent-orchestrator/SKILL.md +22 -0
- package/.agent/skills/agent-orchestrator/scripts/sync-agents.sh +61 -0
- package/.agent/skills/knowledge-lattice/SKILL.md +23 -0
- package/.agent/skills/knowledge-lattice/scripts/lattice-extract.py +107 -0
- package/.agent/skills/resource-vault/SKILL.md +30 -0
- package/.agent/skills/resource-vault/scripts/vault-ingest.py +80 -0
- package/.agent/skills/sites-integrity/SKILL.md +28 -0
- package/.agent/skills/stack-auditor/SKILL.md +25 -0
- package/.agent/sources.md +20 -0
- package/.agent/stack-auditor.md +47 -0
- package/.agent/standards.md +36 -0
- package/.agent/strategy.md +65 -0
- package/.agent/vault-schema.md +53 -0
- package/.agent/voice.md +27 -0
- package/.agent/workflows/sync-agents.md +14 -0
- package/.env.example +5 -0
- package/.env.production +3 -0
- package/DISTRIBUTION-PLAN.md +33 -0
- package/HOSTED_SETUP.md +54 -0
- package/LANDING_PAGE_DESIGN.md +46 -0
- package/MANUAL_VERCEL_STEPS.md +39 -0
- package/PRODUCT-ROADMAP.md +241 -0
- package/PROVISIONING_GUIDE.md +39 -0
- package/README.md +38 -0
- package/ROADMAP.md +21 -0
- package/SYNC-ENGINE-SPEC.md +257 -0
- package/build/core/531-protocol.d.ts +26 -0
- package/build/core/531-protocol.js +87 -0
- package/build/core/531-protocol.js.map +1 -0
- package/build/core/531-rule.d.ts +26 -0
- package/build/core/531-rule.js +106 -0
- package/build/core/531-rule.js.map +1 -0
- package/build/core/auth.d.ts +1 -0
- package/build/core/auth.js +24 -0
- package/build/core/auth.js.map +1 -0
- package/build/core/consent-manager.d.ts +17 -0
- package/build/core/consent-manager.js +104 -0
- package/build/core/consent-manager.js.map +1 -0
- package/build/core/csp.d.ts +12 -0
- package/build/core/csp.js +20 -0
- package/build/core/csp.js.map +1 -0
- package/build/core/engagement-analyzer.d.ts +42 -0
- package/build/core/engagement-analyzer.js +71 -0
- package/build/core/engagement-analyzer.js.map +1 -0
- package/build/core/governor.d.ts +106 -0
- package/build/core/governor.js +405 -0
- package/build/core/governor.js.map +1 -0
- package/build/core/life-area-mapper.d.ts +39 -0
- package/build/core/life-area-mapper.js +73 -0
- package/build/core/life-area-mapper.js.map +1 -0
- package/build/core/methodology.d.ts +39 -0
- package/build/core/methodology.js +164 -0
- package/build/core/methodology.js.map +1 -0
- package/build/core/pingala.d.ts +31 -0
- package/build/core/pingala.js +56 -0
- package/build/core/pingala.js.map +1 -0
- package/build/core/sdk-adapter.d.ts +6 -0
- package/build/core/sdk-adapter.js +33 -0
- package/build/core/sdk-adapter.js.map +1 -0
- package/build/cs-agent-core/sdk/index.d.ts +6 -0
- package/build/cs-agent-core/sdk/index.js +18 -0
- package/build/cs-agent-core/sdk/index.js.map +1 -0
- package/build/cs-agent-core/sdk/patterns/index.d.ts +3 -0
- package/build/cs-agent-core/sdk/patterns/index.js +37 -0
- package/build/cs-agent-core/sdk/patterns/index.js.map +1 -0
- package/build/cs-agent-core/sdk/patterns/registry.d.ts +4 -0
- package/build/cs-agent-core/sdk/patterns/registry.js +80 -0
- package/build/cs-agent-core/sdk/patterns/registry.js.map +1 -0
- package/build/cs-agent-core/sdk/telemetry/buffer.d.ts +9 -0
- package/build/cs-agent-core/sdk/telemetry/buffer.js +47 -0
- package/build/cs-agent-core/sdk/telemetry/buffer.js.map +1 -0
- package/build/cs-agent-core/sdk/telemetry/scrubber.d.ts +3 -0
- package/build/cs-agent-core/sdk/telemetry/scrubber.js +13 -0
- package/build/cs-agent-core/sdk/telemetry/scrubber.js.map +1 -0
- package/build/cs-agent-core/sdk/telemetry/types.d.ts +50 -0
- package/build/cs-agent-core/sdk/telemetry/types.js +2 -0
- package/build/cs-agent-core/sdk/telemetry/types.js.map +1 -0
- package/build/cs-agent-core/sdk/types/decision.d.ts +18 -0
- package/build/cs-agent-core/sdk/types/decision.js +2 -0
- package/build/cs-agent-core/sdk/types/decision.js.map +1 -0
- package/build/cs-agent-core/sdk/types/index.d.ts +4 -0
- package/build/cs-agent-core/sdk/types/index.js +5 -0
- package/build/cs-agent-core/sdk/types/index.js.map +1 -0
- package/build/cs-agent-core/sdk/types/pattern.d.ts +17 -0
- package/build/cs-agent-core/sdk/types/pattern.js +2 -0
- package/build/cs-agent-core/sdk/types/pattern.js.map +1 -0
- package/build/cs-agent-core/sdk/types/stack.d.ts +8 -0
- package/build/cs-agent-core/sdk/types/stack.js +2 -0
- package/build/cs-agent-core/sdk/types/stack.js.map +1 -0
- package/build/cs-agent-core/sdk/types/tool.d.ts +9 -0
- package/build/cs-agent-core/sdk/types/tool.js +2 -0
- package/build/cs-agent-core/sdk/types/tool.js.map +1 -0
- package/build/cs-agent-core/sdk/validator/csi.d.ts +2 -0
- package/build/cs-agent-core/sdk/validator/csi.js +24 -0
- package/build/cs-agent-core/sdk/validator/csi.js.map +1 -0
- package/build/cs-agent-core/sdk/validator/index.d.ts +2 -0
- package/build/cs-agent-core/sdk/validator/index.js +3 -0
- package/build/cs-agent-core/sdk/validator/index.js.map +1 -0
- package/build/cs-agent-core/sdk/validator/rules/geometry.d.ts +11 -0
- package/build/cs-agent-core/sdk/validator/rules/geometry.js +22 -0
- package/build/cs-agent-core/sdk/validator/rules/geometry.js.map +1 -0
- package/build/cs-agent-core/sdk/validator/validate.d.ts +2 -0
- package/build/cs-agent-core/sdk/validator/validate.js +46 -0
- package/build/cs-agent-core/sdk/validator/validate.js.map +1 -0
- package/build/index.d.ts +2 -0
- package/build/index.js +444 -0
- package/build/index.js.map +1 -0
- package/build/pingala-mcp/src/core/531-rule.d.ts +26 -0
- package/build/pingala-mcp/src/core/531-rule.js +96 -0
- package/build/pingala-mcp/src/core/531-rule.js.map +1 -0
- package/build/pingala-mcp/src/core/auth.d.ts +1 -0
- package/build/pingala-mcp/src/core/auth.js +15 -0
- package/build/pingala-mcp/src/core/auth.js.map +1 -0
- package/build/pingala-mcp/src/core/consent-manager.d.ts +17 -0
- package/build/pingala-mcp/src/core/consent-manager.js +104 -0
- package/build/pingala-mcp/src/core/consent-manager.js.map +1 -0
- package/build/pingala-mcp/src/core/csp.d.ts +12 -0
- package/build/pingala-mcp/src/core/csp.js +20 -0
- package/build/pingala-mcp/src/core/csp.js.map +1 -0
- package/build/pingala-mcp/src/core/engagement-analyzer.d.ts +42 -0
- package/build/pingala-mcp/src/core/engagement-analyzer.js +71 -0
- package/build/pingala-mcp/src/core/engagement-analyzer.js.map +1 -0
- package/build/pingala-mcp/src/core/governor.d.ts +104 -0
- package/build/pingala-mcp/src/core/governor.js +359 -0
- package/build/pingala-mcp/src/core/governor.js.map +1 -0
- package/build/pingala-mcp/src/core/life-area-mapper.d.ts +39 -0
- package/build/pingala-mcp/src/core/life-area-mapper.js +73 -0
- package/build/pingala-mcp/src/core/life-area-mapper.js.map +1 -0
- package/build/pingala-mcp/src/core/methodology.d.ts +39 -0
- package/build/pingala-mcp/src/core/methodology.js +164 -0
- package/build/pingala-mcp/src/core/methodology.js.map +1 -0
- package/build/pingala-mcp/src/core/pingala.d.ts +25 -0
- package/build/pingala-mcp/src/core/pingala.js +56 -0
- package/build/pingala-mcp/src/core/pingala.js.map +1 -0
- package/build/pingala-mcp/src/core/sdk-adapter.d.ts +6 -0
- package/build/pingala-mcp/src/core/sdk-adapter.js +33 -0
- package/build/pingala-mcp/src/core/sdk-adapter.js.map +1 -0
- package/build/pingala-mcp/src/index.d.ts +1 -0
- package/build/pingala-mcp/src/index.js +221 -0
- package/build/pingala-mcp/src/index.js.map +1 -0
- package/build/pingala-mcp/src/test-l3.d.ts +1 -0
- package/build/pingala-mcp/src/test-l3.js +35 -0
- package/build/pingala-mcp/src/test-l3.js.map +1 -0
- package/build/pingala-mcp/src/tools/audit-workspace.d.ts +16 -0
- package/build/pingala-mcp/src/tools/audit-workspace.js +39 -0
- package/build/pingala-mcp/src/tools/audit-workspace.js.map +1 -0
- package/build/pingala-mcp/src/tools/calculate-csi.d.ts +24 -0
- package/build/pingala-mcp/src/tools/calculate-csi.js +29 -0
- package/build/pingala-mcp/src/tools/calculate-csi.js.map +1 -0
- package/build/pingala-mcp/src/tools/cs-audit.d.ts +54 -0
- package/build/pingala-mcp/src/tools/cs-audit.js +310 -0
- package/build/pingala-mcp/src/tools/cs-audit.js.map +1 -0
- package/build/pingala-mcp/src/tools/get-governance-context.d.ts +11 -0
- package/build/pingala-mcp/src/tools/get-governance-context.js +16 -0
- package/build/pingala-mcp/src/tools/get-governance-context.js.map +1 -0
- package/build/pingala-mcp/src/tools/validate-stack-change.d.ts +41 -0
- package/build/pingala-mcp/src/tools/validate-stack-change.js +35 -0
- package/build/pingala-mcp/src/tools/validate-stack-change.js.map +1 -0
- package/build/sdk/index.d.ts +6 -0
- package/build/sdk/index.js +18 -0
- package/build/sdk/index.js.map +1 -0
- package/build/sdk/patterns/index.d.ts +3 -0
- package/build/sdk/patterns/index.js +37 -0
- package/build/sdk/patterns/index.js.map +1 -0
- package/build/sdk/patterns/registry.d.ts +4 -0
- package/build/sdk/patterns/registry.js +80 -0
- package/build/sdk/patterns/registry.js.map +1 -0
- package/build/sdk/telemetry/buffer.d.ts +9 -0
- package/build/sdk/telemetry/buffer.js +47 -0
- package/build/sdk/telemetry/buffer.js.map +1 -0
- package/build/sdk/telemetry/scrubber.d.ts +3 -0
- package/build/sdk/telemetry/scrubber.js +13 -0
- package/build/sdk/telemetry/scrubber.js.map +1 -0
- package/build/sdk/telemetry/types.d.ts +50 -0
- package/build/sdk/telemetry/types.js +2 -0
- package/build/sdk/telemetry/types.js.map +1 -0
- package/build/sdk/types/decision.d.ts +18 -0
- package/build/sdk/types/decision.js +2 -0
- package/build/sdk/types/decision.js.map +1 -0
- package/build/sdk/types/index.d.ts +4 -0
- package/build/sdk/types/index.js +5 -0
- package/build/sdk/types/index.js.map +1 -0
- package/build/sdk/types/pattern.d.ts +17 -0
- package/build/sdk/types/pattern.js +2 -0
- package/build/sdk/types/pattern.js.map +1 -0
- package/build/sdk/types/stack.d.ts +8 -0
- package/build/sdk/types/stack.js +2 -0
- package/build/sdk/types/stack.js.map +1 -0
- package/build/sdk/types/tool.d.ts +9 -0
- package/build/sdk/types/tool.js +2 -0
- package/build/sdk/types/tool.js.map +1 -0
- package/build/sdk/validator/csi.d.ts +2 -0
- package/build/sdk/validator/csi.js +24 -0
- package/build/sdk/validator/csi.js.map +1 -0
- package/build/sdk/validator/index.d.ts +2 -0
- package/build/sdk/validator/index.js +3 -0
- package/build/sdk/validator/index.js.map +1 -0
- package/build/sdk/validator/rules/geometry.d.ts +11 -0
- package/build/sdk/validator/rules/geometry.js +22 -0
- package/build/sdk/validator/rules/geometry.js.map +1 -0
- package/build/sdk/validator/validate.d.ts +2 -0
- package/build/sdk/validator/validate.js +46 -0
- package/build/sdk/validator/validate.js.map +1 -0
- package/build/src/core/531-rule.d.ts +26 -0
- package/build/src/core/531-rule.js +96 -0
- package/build/src/core/531-rule.js.map +1 -0
- package/build/src/core/auth.d.ts +1 -0
- package/build/src/core/auth.js +15 -0
- package/build/src/core/auth.js.map +1 -0
- package/build/src/core/consent-manager.d.ts +17 -0
- package/build/src/core/consent-manager.js +104 -0
- package/build/src/core/consent-manager.js.map +1 -0
- package/build/src/core/csp.d.ts +12 -0
- package/build/src/core/csp.js +20 -0
- package/build/src/core/csp.js.map +1 -0
- package/build/src/core/engagement-analyzer.d.ts +42 -0
- package/build/src/core/engagement-analyzer.js +71 -0
- package/build/src/core/engagement-analyzer.js.map +1 -0
- package/build/src/core/governor.d.ts +104 -0
- package/build/src/core/governor.js +371 -0
- package/build/src/core/governor.js.map +1 -0
- package/build/src/core/life-area-mapper.d.ts +39 -0
- package/build/src/core/life-area-mapper.js +73 -0
- package/build/src/core/life-area-mapper.js.map +1 -0
- package/build/src/core/methodology.d.ts +39 -0
- package/build/src/core/methodology.js +164 -0
- package/build/src/core/methodology.js.map +1 -0
- package/build/src/core/pingala.d.ts +25 -0
- package/build/src/core/pingala.js +56 -0
- package/build/src/core/pingala.js.map +1 -0
- package/build/src/core/sdk-adapter.d.ts +8 -0
- package/build/src/core/sdk-adapter.js +34 -0
- package/build/src/core/sdk-adapter.js.map +1 -0
- package/build/src/index.d.ts +2 -0
- package/build/src/index.js +333 -0
- package/build/src/index.js.map +1 -0
- package/build/src/test-l3.d.ts +1 -0
- package/build/src/test-l3.js +35 -0
- package/build/src/test-l3.js.map +1 -0
- package/build/src/tools/audit-workspace.d.ts +16 -0
- package/build/src/tools/audit-workspace.js +39 -0
- package/build/src/tools/audit-workspace.js.map +1 -0
- package/build/src/tools/calculate-csi.d.ts +24 -0
- package/build/src/tools/calculate-csi.js +29 -0
- package/build/src/tools/calculate-csi.js.map +1 -0
- package/build/src/tools/cs-audit.d.ts +54 -0
- package/build/src/tools/cs-audit.js +310 -0
- package/build/src/tools/cs-audit.js.map +1 -0
- package/build/src/tools/get-governance-context.d.ts +11 -0
- package/build/src/tools/get-governance-context.js +16 -0
- package/build/src/tools/get-governance-context.js.map +1 -0
- package/build/src/tools/validate-stack-change.d.ts +41 -0
- package/build/src/tools/validate-stack-change.js +35 -0
- package/build/src/tools/validate-stack-change.js.map +1 -0
- package/build/test-l3.d.ts +1 -0
- package/build/test-l3.js +35 -0
- package/build/test-l3.js.map +1 -0
- package/build/tools/analyze-stack.d.ts +40 -0
- package/build/tools/analyze-stack.js +121 -0
- package/build/tools/analyze-stack.js.map +1 -0
- package/build/tools/audit-workspace.d.ts +16 -0
- package/build/tools/audit-workspace.js +39 -0
- package/build/tools/audit-workspace.js.map +1 -0
- package/build/tools/calculate-csi.d.ts +26 -0
- package/build/tools/calculate-csi.js +30 -0
- package/build/tools/calculate-csi.js.map +1 -0
- package/build/tools/cs-audit.d.ts +43 -0
- package/build/tools/cs-audit.js +330 -0
- package/build/tools/cs-audit.js.map +1 -0
- package/build/tools/get-governance-context.d.ts +11 -0
- package/build/tools/get-governance-context.js +61 -0
- package/build/tools/get-governance-context.js.map +1 -0
- package/build/tools/validate-stack-change.d.ts +41 -0
- package/build/tools/validate-stack-change.js +54 -0
- package/build/tools/validate-stack-change.js.map +1 -0
- package/package.json +34 -0
- package/scripts/cloud-bridge.js +62 -0
- package/scripts/generate-token.js +13 -0
- package/src/core/531-rule.ts +148 -0
- package/src/core/auth.ts +42 -0
- package/src/core/consent-manager.ts +134 -0
- package/src/core/csp.ts +40 -0
- package/src/core/engagement-analyzer.ts +122 -0
- package/src/core/governor.ts +522 -0
- package/src/core/life-area-mapper.ts +138 -0
- package/src/core/methodology.ts +256 -0
- package/src/core/pingala.ts +77 -0
- package/src/core/sdk-adapter.ts +52 -0
- package/src/index.ts +562 -0
- package/src/test-l3.ts +45 -0
- package/src/tools/analyze-stack.ts +153 -0
- package/src/tools/audit-workspace.ts +50 -0
- package/src/tools/calculate-csi.ts +38 -0
- package/src/tools/cs-audit.ts +384 -0
- package/src/tools/get-governance-context.ts +69 -0
- package/src/tools/validate-stack-change.ts +71 -0
- package/src/types.d.ts +2 -0
- package/tsconfig.json +40 -0
- package/vercel.json +15 -0
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure logic for the 5:3:1 Rule — the core constraint of the Conscious Stack Protocol (CSP).
|
|
3
|
+
* This module validates stack configurations against the CSP's numeric requirements.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export interface ToolInstance {
|
|
7
|
+
name: string;
|
|
8
|
+
category: string;
|
|
9
|
+
role: 'Anchor' | 'Active' | 'Supporting' | 'Unknown';
|
|
10
|
+
functionId?: string; // The "Functional Node" or Bāguà Room (e.g., "browser", "comms")
|
|
11
|
+
context?: string; // System context (e.g., "desktop", "mobile")
|
|
12
|
+
isAdapter?: boolean; // Set to true if this tool is a contextual window into another node
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface StackConfiguration {
|
|
16
|
+
tools: ToolInstance[];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface ValidationResult {
|
|
20
|
+
isValid: boolean;
|
|
21
|
+
score: number; // 0-100
|
|
22
|
+
violations: string[];
|
|
23
|
+
recommendations: string[];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export class Rule531 {
|
|
27
|
+
static readonly NORMS = {
|
|
28
|
+
Anchor: 1,
|
|
29
|
+
Active: 3,
|
|
30
|
+
Support: 5,
|
|
31
|
+
Total: 9
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* diagnostic validation of stack configuration against Stability Norms.
|
|
36
|
+
* Respects Contextual Scaling (Core vs. Substacks).
|
|
37
|
+
*/
|
|
38
|
+
static validate(config: StackConfiguration): ValidationResult {
|
|
39
|
+
const strain_vectors: string[] = [];
|
|
40
|
+
const recommendations: string[] = [];
|
|
41
|
+
|
|
42
|
+
// 1. Group tools by context
|
|
43
|
+
const contexts: Record<string, ToolInstance[]> = {};
|
|
44
|
+
const coreTools: ToolInstance[] = [];
|
|
45
|
+
|
|
46
|
+
config.tools.forEach(t => {
|
|
47
|
+
const ctx = t.context?.toLowerCase() || 'core';
|
|
48
|
+
if (ctx === 'core') {
|
|
49
|
+
coreTools.push(t);
|
|
50
|
+
} else {
|
|
51
|
+
if (!contexts[ctx]) contexts[ctx] = [];
|
|
52
|
+
contexts[ctx].push(t);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// Helper to analyze a specific toolset
|
|
57
|
+
const analyzeToolset = (tools: ToolInstance[]) => {
|
|
58
|
+
const functionalNodes: Record<string, ToolInstance[]> = {};
|
|
59
|
+
const unclassifiedTools: ToolInstance[] = [];
|
|
60
|
+
|
|
61
|
+
tools.forEach(t => {
|
|
62
|
+
if (t.functionId) {
|
|
63
|
+
if (!functionalNodes[t.functionId]) functionalNodes[t.functionId] = [];
|
|
64
|
+
functionalNodes[t.functionId].push(t);
|
|
65
|
+
} else {
|
|
66
|
+
unclassifiedTools.push(t);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
let anchor = 0;
|
|
71
|
+
let active = 0;
|
|
72
|
+
let support = 0;
|
|
73
|
+
let unknown = 0;
|
|
74
|
+
|
|
75
|
+
// Count functional nodes
|
|
76
|
+
Object.values(functionalNodes).forEach(cluster => {
|
|
77
|
+
const hasAnchor = cluster.some(t => t.role === 'Anchor');
|
|
78
|
+
const hasActive = cluster.some(t => t.role === 'Active');
|
|
79
|
+
const hasSupport = cluster.some(t => t.role === 'Supporting');
|
|
80
|
+
|
|
81
|
+
if (hasAnchor) anchor++;
|
|
82
|
+
else if (hasActive) active++;
|
|
83
|
+
else if (hasSupport) support++;
|
|
84
|
+
else unknown++;
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
// Count unclassified
|
|
88
|
+
unclassifiedTools.forEach(t => {
|
|
89
|
+
if (t.role === 'Anchor') anchor++;
|
|
90
|
+
else if (t.role === 'Active') active++;
|
|
91
|
+
else if (t.role === 'Supporting') support++;
|
|
92
|
+
else unknown++;
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
return { anchor, active, support, unknown, total: anchor + active + support };
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
// 2. Validate Core (Crystalline Norm)
|
|
99
|
+
const coreMetrics = analyzeToolset(coreTools);
|
|
100
|
+
|
|
101
|
+
if (coreMetrics.anchor === 0) {
|
|
102
|
+
strain_vectors.push("Core Strain: No Anchor defined. Stability requires a center.");
|
|
103
|
+
recommendations.push("Identify a single 'Anchor' node for your Core.");
|
|
104
|
+
} else if (coreMetrics.anchor > this.NORMS.Anchor) {
|
|
105
|
+
strain_vectors.push(`Core Strain: Multiple Anchors (${coreMetrics.anchor}). Core must have exactly one.`);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (coreMetrics.active > this.NORMS.Active) {
|
|
109
|
+
strain_vectors.push(`Core Strain: Active Overload (${coreMetrics.active}/${this.NORMS.Active}). Move excess to a Substack.`);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (coreMetrics.support > this.NORMS.Support) {
|
|
113
|
+
strain_vectors.push(`Core Strain: Supporting Overload (${coreMetrics.support}/${this.NORMS.Support}).`);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// 3. Validate Contexts (Diagnostic)
|
|
117
|
+
const contextMetrics: Record<string, { anchor: number; active: number; support: number }> = {};
|
|
118
|
+
|
|
119
|
+
Object.entries(contexts).forEach(([ctx, tools]) => {
|
|
120
|
+
const metrics = analyzeToolset(tools);
|
|
121
|
+
contextMetrics[ctx] = { anchor: metrics.anchor, active: metrics.active, support: metrics.support };
|
|
122
|
+
|
|
123
|
+
if (metrics.total > this.NORMS.Total) {
|
|
124
|
+
strain_vectors.push(`Context Strain (${ctx}): Total load (${metrics.total}) exceeds Rule of 9.`);
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
// 4. Calculate Score (Diagnostic Health)
|
|
129
|
+
let score = 100;
|
|
130
|
+
score -= strain_vectors.length * 10;
|
|
131
|
+
if (coreMetrics.unknown > 0) score -= 5;
|
|
132
|
+
score = Math.max(0, score);
|
|
133
|
+
|
|
134
|
+
return {
|
|
135
|
+
isValid: strain_vectors.length === 0,
|
|
136
|
+
score,
|
|
137
|
+
violations: strain_vectors, // Mapped for backward compatibility
|
|
138
|
+
recommendations,
|
|
139
|
+
// Extended return for new UI
|
|
140
|
+
// @ts-ignore - dynamic property
|
|
141
|
+
geometry: {
|
|
142
|
+
total_functional_slots: coreMetrics.total + Object.values(contextMetrics).reduce((a, b) => a + (b.anchor + b.active + b.support), 0),
|
|
143
|
+
core: { anchor: coreMetrics.anchor, active: coreMetrics.active, support: coreMetrics.support },
|
|
144
|
+
contexts: contextMetrics
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
}
|
package/src/core/auth.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// No type imports for express due to offline environment
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Validates the Authorization token for MCP access.
|
|
6
|
+
* Expects: Authorization: Bearer <TOKEN>
|
|
7
|
+
*/
|
|
8
|
+
export const validateToken = (req: any, res: any, next: any) => {
|
|
9
|
+
// Skip auth for preflight
|
|
10
|
+
if (req.method === "OPTIONS") return next();
|
|
11
|
+
|
|
12
|
+
let token;
|
|
13
|
+
|
|
14
|
+
// 1. Check Header
|
|
15
|
+
const authHeader = req.headers.authorization;
|
|
16
|
+
if (authHeader && authHeader.startsWith("Bearer ")) {
|
|
17
|
+
token = authHeader.split(" ")[1];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// 2. Check Query Param (Fallback)
|
|
21
|
+
// This is required because native EventSource in browsers/Node often cannot set headers
|
|
22
|
+
if (!token && req.query && req.query.token) {
|
|
23
|
+
token = req.query.token;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (!token) {
|
|
27
|
+
return res.status(401).json({ error: "Missing or invalid Authorization credentials" });
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// VALID_TOKENS should be a comma-separated list of strings in the environment
|
|
31
|
+
const validTokens = (process.env.VALID_TOKENS || "").split(",").map(t => t.trim());
|
|
32
|
+
|
|
33
|
+
// HARDCODED FALLBACK for current session (Vercel CLI sync fix)
|
|
34
|
+
const sessionToken = "7df658500907f854ce76eaf00e964177";
|
|
35
|
+
if (!validTokens.includes(sessionToken)) validTokens.push(sessionToken);
|
|
36
|
+
|
|
37
|
+
if (!validTokens.includes(token)) {
|
|
38
|
+
return res.status(401).json({ error: "Invalid token" });
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
next();
|
|
42
|
+
};
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import * as os from "node:os";
|
|
4
|
+
import process from "node:process";
|
|
5
|
+
import yaml from "js-yaml";
|
|
6
|
+
|
|
7
|
+
export interface ConsentState {
|
|
8
|
+
l2_accepted: boolean;
|
|
9
|
+
l2_accepted_at?: string;
|
|
10
|
+
l3_accepted: boolean;
|
|
11
|
+
l3_accepted_at?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* ConsentManager: Handles persistence of user consent for deep auditing tiers.
|
|
16
|
+
* Supports both global fallback and workspace-local storage in .agent/governance.yaml.
|
|
17
|
+
*/
|
|
18
|
+
export class ConsentManager {
|
|
19
|
+
private static dataDir: string = process.env.CSTACK_DATA_DIR || path.join(os.homedir(), ".cstack-data");
|
|
20
|
+
private static globalConsentFile: string = "consent-state.json";
|
|
21
|
+
private static workspacePath: string | null = null;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Set the current workspace path for local consent state.
|
|
25
|
+
*/
|
|
26
|
+
static setWorkspace(workspacePath: string): void {
|
|
27
|
+
this.workspacePath = workspacePath;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
private static getFilePath(): string {
|
|
31
|
+
// 1. Check workspace-local .agent/governance.yaml
|
|
32
|
+
if (this.workspacePath) {
|
|
33
|
+
const agentDir = path.join(this.workspacePath, ".agent");
|
|
34
|
+
if (fs.existsSync(agentDir)) {
|
|
35
|
+
return path.join(agentDir, "governance.yaml");
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// 2. Fallback to global data dir
|
|
40
|
+
if (!fs.existsSync(this.dataDir)) {
|
|
41
|
+
fs.mkdirSync(this.dataDir, { recursive: true });
|
|
42
|
+
}
|
|
43
|
+
return path.join(this.dataDir, this.globalConsentFile);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Get current consent state for the context (workspace or global).
|
|
48
|
+
*/
|
|
49
|
+
static getConsentState(): ConsentState {
|
|
50
|
+
const filePath = this.getFilePath();
|
|
51
|
+
const defaultState: ConsentState = {
|
|
52
|
+
l2_accepted: false,
|
|
53
|
+
l3_accepted: false
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
if (fs.existsSync(filePath)) {
|
|
57
|
+
try {
|
|
58
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
59
|
+
if (filePath.endsWith(".yaml") || filePath.endsWith(".yml")) {
|
|
60
|
+
const parsed = yaml.load(content) as any;
|
|
61
|
+
return {
|
|
62
|
+
l2_accepted: parsed?.consent?.l2_accepted ?? false,
|
|
63
|
+
l2_accepted_at: parsed?.consent?.l2_accepted_at,
|
|
64
|
+
l3_accepted: parsed?.consent?.l3_accepted ?? false,
|
|
65
|
+
l3_accepted_at: parsed?.consent?.l3_accepted_at
|
|
66
|
+
};
|
|
67
|
+
} else {
|
|
68
|
+
return JSON.parse(content);
|
|
69
|
+
}
|
|
70
|
+
} catch (e) {
|
|
71
|
+
console.error(`[ConsentManager] Error reading consent from ${filePath}:`, e);
|
|
72
|
+
return defaultState;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return defaultState;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Update consent for a specific level.
|
|
80
|
+
*/
|
|
81
|
+
static setConsent(level: 'L2' | 'L3', accepted: boolean): void {
|
|
82
|
+
const filePath = this.getFilePath();
|
|
83
|
+
const state = this.getConsentState();
|
|
84
|
+
|
|
85
|
+
if (level === 'L2') {
|
|
86
|
+
state.l2_accepted = accepted;
|
|
87
|
+
if (accepted) state.l2_accepted_at = new Date().toISOString();
|
|
88
|
+
} else if (level === 'L3') {
|
|
89
|
+
state.l3_accepted = accepted;
|
|
90
|
+
if (accepted) state.l3_accepted_at = new Date().toISOString();
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
try {
|
|
94
|
+
if (filePath.endsWith(".yaml") || filePath.endsWith(".yml")) {
|
|
95
|
+
let existing: any = {};
|
|
96
|
+
if (fs.existsSync(filePath)) {
|
|
97
|
+
existing = yaml.load(fs.readFileSync(filePath, "utf-8")) || {};
|
|
98
|
+
}
|
|
99
|
+
existing.consent = state;
|
|
100
|
+
fs.writeFileSync(filePath, yaml.dump(existing, { indent: 2 }));
|
|
101
|
+
} else {
|
|
102
|
+
fs.writeFileSync(filePath, JSON.stringify(state, null, 2));
|
|
103
|
+
}
|
|
104
|
+
} catch (e) {
|
|
105
|
+
console.error(`[ConsentManager] Error writing consent to ${filePath}:`, e);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Check if a specific level is authorized.
|
|
111
|
+
*/
|
|
112
|
+
static isAuthorized(level: 'L1' | 'L2' | 'L3', practitionerOverride: boolean = false): boolean {
|
|
113
|
+
if (level === 'L1') return true;
|
|
114
|
+
|
|
115
|
+
const state = this.getConsentState();
|
|
116
|
+
if (level === 'L2') {
|
|
117
|
+
return practitionerOverride || state.l2_accepted;
|
|
118
|
+
}
|
|
119
|
+
if (level === 'L3') {
|
|
120
|
+
// L3 requires L2 to be authorized AND L3 consent
|
|
121
|
+
return practitionerOverride || (this.isAuthorized('L2', false) && state.l3_accepted);
|
|
122
|
+
}
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Helper to get the highest currently authorized level as a number.
|
|
128
|
+
*/
|
|
129
|
+
static getCurrentConsentLevel(): number {
|
|
130
|
+
if (this.isAuthorized('L3')) return 3;
|
|
131
|
+
if (this.isAuthorized('L2')) return 2;
|
|
132
|
+
return 1;
|
|
133
|
+
}
|
|
134
|
+
}
|
package/src/core/csp.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Conscious Stack Protocol (CSP) v1.0
|
|
3
|
+
* The technical handshake for conscious governance.
|
|
4
|
+
* Aggregates the 5:3:1 Rule, Maturity Gates, and Consent Levels.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { Rule531, type ValidationResult as RuleValidation } from './531-rule.js';
|
|
8
|
+
import { Governor } from './governor.js';
|
|
9
|
+
import { ConsentManager } from './consent-manager.js';
|
|
10
|
+
|
|
11
|
+
export interface CSPCompliance {
|
|
12
|
+
version: '1.0';
|
|
13
|
+
is_compliant: boolean; // True if 5:3:1 Rule passes
|
|
14
|
+
rule_validation: RuleValidation; // Result from Rule531.validate()
|
|
15
|
+
consent_level: number; // Current L1/L2/L3 consent
|
|
16
|
+
maturity_level: number; // Stack maturity (1-5)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export class ConsciousStackProtocol {
|
|
20
|
+
static readonly VERSION = '1.0';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Performs the CSP handshake.
|
|
24
|
+
* Returns a summary of protocol compliance for the current stack.
|
|
25
|
+
*/
|
|
26
|
+
static getCompliance(): CSPCompliance {
|
|
27
|
+
const stack = Governor.getStack();
|
|
28
|
+
const ruleValidation = Rule531.validate({ tools: stack });
|
|
29
|
+
const maturityState = Governor.getMaturityState();
|
|
30
|
+
const consentLevel = ConsentManager.getCurrentConsentLevel();
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
version: this.VERSION,
|
|
34
|
+
is_compliant: ruleValidation.isValid,
|
|
35
|
+
rule_validation: ruleValidation,
|
|
36
|
+
consent_level: consentLevel,
|
|
37
|
+
maturity_level: maturityState.level
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { type ToolInstance } from "./531-rule.js";
|
|
2
|
+
|
|
3
|
+
export interface EngagementProfile {
|
|
4
|
+
tier: 'high_engagement' | 'contextual_utility' | 'passive_background' | 'fragmentation_risk';
|
|
5
|
+
avgDailyMinutes?: number;
|
|
6
|
+
usagePattern?: 'consistent' | 'sporadic' | 'single_spike';
|
|
7
|
+
anomalyFlag?: boolean;
|
|
8
|
+
anomalyNote?: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface ToolWithEngagement extends ToolInstance {
|
|
12
|
+
avgDailyMinutes?: number;
|
|
13
|
+
usagePattern?: 'consistent' | 'sporadic' | 'single_spike';
|
|
14
|
+
engagement?: EngagementProfile;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface EngagementAnalysis {
|
|
18
|
+
high_engagement: ToolWithEngagement[];
|
|
19
|
+
contextual_utility: ToolWithEngagement[];
|
|
20
|
+
passive_background: ToolWithEngagement[];
|
|
21
|
+
fragmentation_risk: ToolWithEngagement[];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export class EngagementAnalyzer {
|
|
25
|
+
/**
|
|
26
|
+
* Classifies tools into engagement tiers based on usage data.
|
|
27
|
+
*/
|
|
28
|
+
static classifyByEngagement(tools: ToolWithEngagement[]): EngagementAnalysis {
|
|
29
|
+
const analysis: EngagementAnalysis = {
|
|
30
|
+
high_engagement: [],
|
|
31
|
+
contextual_utility: [],
|
|
32
|
+
passive_background: [],
|
|
33
|
+
fragmentation_risk: []
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
tools.forEach(tool => {
|
|
37
|
+
const minutes = tool.avgDailyMinutes ?? 0;
|
|
38
|
+
const pattern = tool.usagePattern ?? 'sporadic';
|
|
39
|
+
|
|
40
|
+
if (minutes >= 15 || (minutes >= 10 && pattern === 'consistent')) {
|
|
41
|
+
analysis.high_engagement.push(tool);
|
|
42
|
+
} else if (minutes > 5 || (minutes > 0 && pattern === 'consistent')) {
|
|
43
|
+
analysis.contextual_utility.push(tool);
|
|
44
|
+
} else {
|
|
45
|
+
analysis.passive_background.push(tool);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
return analysis;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Identifies multiple tools serving the same functional node (fragmentation).
|
|
54
|
+
*/
|
|
55
|
+
static detectFragmentation(tools: ToolWithEngagement[]) {
|
|
56
|
+
const clusters: Record<string, ToolWithEngagement[]> = {};
|
|
57
|
+
|
|
58
|
+
// Group by functionId or category if functionId is missing
|
|
59
|
+
tools.forEach(tool => {
|
|
60
|
+
const functionKey = tool.functionId || tool.category || "Uncategorized";
|
|
61
|
+
if (functionKey === "Uncategorized") return;
|
|
62
|
+
|
|
63
|
+
if (!clusters[functionKey]) clusters[functionKey] = [];
|
|
64
|
+
clusters[functionKey].push(tool);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// Only return clusters with more than 1 tool
|
|
68
|
+
return Object.entries(clusters)
|
|
69
|
+
.filter(([_, t]) => t.length > 1)
|
|
70
|
+
.map(([id, t]) => ({
|
|
71
|
+
functionId: id,
|
|
72
|
+
tools: t.map(tool => tool.name),
|
|
73
|
+
primary: t.reduce((prev, current) => (prev.avgDailyMinutes || 0) > (current.avgDailyMinutes || 0) ? prev : current).name
|
|
74
|
+
}));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Flags unusual engagement spikes for investigation.
|
|
79
|
+
*/
|
|
80
|
+
static flagAnomalies(tools: ToolWithEngagement[]) {
|
|
81
|
+
return tools
|
|
82
|
+
.filter(t => t.usagePattern === 'single_spike' && (t.avgDailyMinutes || 0) > 60)
|
|
83
|
+
.map(t => ({
|
|
84
|
+
tool: t.name,
|
|
85
|
+
anomaly: `${t.avgDailyMinutes} min spike detected`,
|
|
86
|
+
note: "Likely a contextual event (meeting, interview, accident) rather than a persistent stack requirement."
|
|
87
|
+
}));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Evaluates if the user has a clear Anchor environment (not just an app).
|
|
92
|
+
*/
|
|
93
|
+
static identifyAnchorEnvironment(tools: ToolWithEngagement[]) {
|
|
94
|
+
const hasChromeAnchor = tools.some(t =>
|
|
95
|
+
t.role === 'Anchor' &&
|
|
96
|
+
t.name.toLowerCase().includes('chrome')
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
const highUseMobile = tools.filter(t => (t.avgDailyMinutes || 0) > 20);
|
|
100
|
+
|
|
101
|
+
if (!hasChromeAnchor && highUseMobile.length > 0) {
|
|
102
|
+
return {
|
|
103
|
+
hasAnchor: false,
|
|
104
|
+
observation: "System appears mobile-native or fragmented. No clear 'Anchor' environment detected.",
|
|
105
|
+
hint: "Is your work moving through intentional slots, or are you operating in a reactive mobile-check-in loop?"
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return { hasAnchor: true };
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Computes a score based on fragmentation (0-100, higher is better).
|
|
114
|
+
*/
|
|
115
|
+
static getFragmentationScore(tools: ToolWithEngagement[]): number {
|
|
116
|
+
const fragClusters = this.detectFragmentation(tools);
|
|
117
|
+
if (fragClusters.length === 0) return 100;
|
|
118
|
+
|
|
119
|
+
// Deduct 20 points per fragment cluster, floor at 0
|
|
120
|
+
return Math.max(0, 100 - (fragClusters.length * 20));
|
|
121
|
+
}
|
|
122
|
+
}
|