@vinaes/succ 1.4.0 → 1.5.37
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/README.md +64 -10
- package/dist/cli.js +71 -1
- package/dist/cli.js.map +1 -1
- package/dist/commands/agents-md.d.ts.map +1 -1
- package/dist/commands/agents-md.js +3 -2
- package/dist/commands/agents-md.js.map +1 -1
- package/dist/commands/analyze-profile.d.ts.map +1 -1
- package/dist/commands/analyze-profile.js +32 -8
- package/dist/commands/analyze-profile.js.map +1 -1
- package/dist/commands/analyze-recursive.d.ts.map +1 -1
- package/dist/commands/analyze-recursive.js +6 -2
- package/dist/commands/analyze-recursive.js.map +1 -1
- package/dist/commands/analyze-utils.d.ts.map +1 -1
- package/dist/commands/analyze-utils.js +17 -4
- package/dist/commands/analyze-utils.js.map +1 -1
- package/dist/commands/benchmark-quality.d.ts.map +1 -1
- package/dist/commands/benchmark-quality.js +11 -4
- package/dist/commands/benchmark-quality.js.map +1 -1
- package/dist/commands/benchmark-sqlite-vec.d.ts.map +1 -1
- package/dist/commands/benchmark-sqlite-vec.js +4 -0
- package/dist/commands/benchmark-sqlite-vec.js.map +1 -1
- package/dist/commands/benchmark.d.ts.map +1 -1
- package/dist/commands/benchmark.js +5 -1
- package/dist/commands/benchmark.js.map +1 -1
- package/dist/commands/codex-chat.d.ts +8 -0
- package/dist/commands/codex-chat.d.ts.map +1 -0
- package/dist/commands/codex-chat.js +161 -0
- package/dist/commands/codex-chat.js.map +1 -0
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +32 -4
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/daemon.d.ts.map +1 -1
- package/dist/commands/daemon.js +13 -4
- package/dist/commands/daemon.js.map +1 -1
- package/dist/commands/index-code.d.ts +4 -0
- package/dist/commands/index-code.d.ts.map +1 -1
- package/dist/commands/index-code.js +1 -1
- package/dist/commands/index-code.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +305 -203
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/memories.d.ts.map +1 -1
- package/dist/commands/memories.js +25 -14
- package/dist/commands/memories.js.map +1 -1
- package/dist/commands/progress.d.ts.map +1 -1
- package/dist/commands/progress.js +3 -2
- package/dist/commands/progress.js.map +1 -1
- package/dist/commands/reindex.d.ts.map +1 -1
- package/dist/commands/reindex.js +54 -36
- package/dist/commands/reindex.js.map +1 -1
- package/dist/commands/retention.d.ts.map +1 -1
- package/dist/commands/retention.js +7 -5
- package/dist/commands/retention.js.map +1 -1
- package/dist/commands/scan-code.d.ts +76 -0
- package/dist/commands/scan-code.d.ts.map +1 -0
- package/dist/commands/scan-code.js +385 -0
- package/dist/commands/scan-code.js.map +1 -0
- package/dist/commands/score.d.ts.map +1 -1
- package/dist/commands/score.js +3 -2
- package/dist/commands/score.js.map +1 -1
- package/dist/commands/session.d.ts +33 -0
- package/dist/commands/session.d.ts.map +1 -0
- package/dist/commands/session.js +163 -0
- package/dist/commands/session.js.map +1 -0
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +254 -15
- package/dist/commands/setup.js.map +1 -1
- package/dist/commands/soul.js +3 -2
- package/dist/commands/soul.js.map +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +14 -5
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/watch.d.ts.map +1 -1
- package/dist/commands/watch.js +13 -4
- package/dist/commands/watch.js.map +1 -1
- package/dist/daemon/analyzer.d.ts.map +1 -1
- package/dist/daemon/analyzer.js +21 -5
- package/dist/daemon/analyzer.js.map +1 -1
- package/dist/daemon/client.d.ts.map +1 -1
- package/dist/daemon/client.js +32 -8
- package/dist/daemon/client.js.map +1 -1
- package/dist/daemon/routes/analyzer.d.ts +3 -0
- package/dist/daemon/routes/analyzer.d.ts.map +1 -0
- package/dist/daemon/routes/analyzer.js +27 -0
- package/dist/daemon/routes/analyzer.js.map +1 -0
- package/dist/daemon/routes/hooks.d.ts +14 -0
- package/dist/daemon/routes/hooks.d.ts.map +1 -0
- package/dist/daemon/routes/hooks.js +1212 -0
- package/dist/daemon/routes/hooks.js.map +1 -0
- package/dist/daemon/routes/memory.d.ts +4 -0
- package/dist/daemon/routes/memory.d.ts.map +1 -0
- package/dist/daemon/routes/memory.js +71 -0
- package/dist/daemon/routes/memory.js.map +1 -0
- package/dist/daemon/routes/reflection.d.ts +10 -0
- package/dist/daemon/routes/reflection.d.ts.map +1 -0
- package/dist/daemon/routes/reflection.js +397 -0
- package/dist/daemon/routes/reflection.js.map +1 -0
- package/dist/daemon/routes/search.d.ts +5 -0
- package/dist/daemon/routes/search.d.ts.map +1 -0
- package/dist/daemon/routes/search.js +93 -0
- package/dist/daemon/routes/search.js.map +1 -0
- package/dist/daemon/routes/sessions.d.ts +3 -0
- package/dist/daemon/routes/sessions.d.ts.map +1 -0
- package/dist/daemon/routes/sessions.js +160 -0
- package/dist/daemon/routes/sessions.js.map +1 -0
- package/dist/daemon/routes/skills.d.ts +3 -0
- package/dist/daemon/routes/skills.d.ts.map +1 -0
- package/dist/daemon/routes/skills.js +36 -0
- package/dist/daemon/routes/skills.js.map +1 -0
- package/dist/daemon/routes/status.d.ts +3 -0
- package/dist/daemon/routes/status.d.ts.map +1 -0
- package/dist/daemon/routes/status.js +47 -0
- package/dist/daemon/routes/status.js.map +1 -0
- package/dist/daemon/routes/types.d.ts +240 -0
- package/dist/daemon/routes/types.d.ts.map +1 -0
- package/dist/daemon/routes/types.js +97 -0
- package/dist/daemon/routes/types.js.map +1 -0
- package/dist/daemon/routes/versioning.d.ts +27 -0
- package/dist/daemon/routes/versioning.d.ts.map +1 -0
- package/dist/daemon/routes/versioning.js +44 -0
- package/dist/daemon/routes/versioning.js.map +1 -0
- package/dist/daemon/routes/watcher.d.ts +3 -0
- package/dist/daemon/routes/watcher.d.ts.map +1 -0
- package/dist/daemon/routes/watcher.js +28 -0
- package/dist/daemon/routes/watcher.js.map +1 -0
- package/dist/daemon/service.d.ts +5 -23
- package/dist/daemon/service.d.ts.map +1 -1
- package/dist/daemon/service.js +177 -935
- package/dist/daemon/service.js.map +1 -1
- package/dist/daemon/session-processor.d.ts +4 -8
- package/dist/daemon/session-processor.d.ts.map +1 -1
- package/dist/daemon/session-processor.js +39 -38
- package/dist/daemon/session-processor.js.map +1 -1
- package/dist/lib/ai-readiness.d.ts.map +1 -1
- package/dist/lib/ai-readiness.js +33 -8
- package/dist/lib/ai-readiness.js.map +1 -1
- package/dist/lib/analyze-state.d.ts.map +1 -1
- package/dist/lib/analyze-state.js +25 -3
- package/dist/lib/analyze-state.js.map +1 -1
- package/dist/lib/auto-memory/consolidation.d.ts +41 -0
- package/dist/lib/auto-memory/consolidation.d.ts.map +1 -0
- package/dist/lib/auto-memory/consolidation.js +151 -0
- package/dist/lib/auto-memory/consolidation.js.map +1 -0
- package/dist/lib/bpe.d.ts.map +1 -1
- package/dist/lib/bpe.js +9 -10
- package/dist/lib/bpe.js.map +1 -1
- package/dist/lib/brain-export.d.ts +65 -0
- package/dist/lib/brain-export.d.ts.map +1 -0
- package/dist/lib/brain-export.js +413 -0
- package/dist/lib/brain-export.js.map +1 -0
- package/dist/lib/checkpoint.d.ts.map +1 -1
- package/dist/lib/checkpoint.js +22 -6
- package/dist/lib/checkpoint.js.map +1 -1
- package/dist/lib/chunker.d.ts.map +1 -1
- package/dist/lib/chunker.js +6 -1
- package/dist/lib/chunker.js.map +1 -1
- package/dist/lib/claude-ws-transport.d.ts.map +1 -1
- package/dist/lib/claude-ws-transport.js +12 -4
- package/dist/lib/claude-ws-transport.js.map +1 -1
- package/dist/lib/command-safety.d.ts +64 -0
- package/dist/lib/command-safety.d.ts.map +1 -0
- package/dist/lib/command-safety.js +625 -0
- package/dist/lib/command-safety.js.map +1 -0
- package/dist/lib/compact-briefing.d.ts.map +1 -1
- package/dist/lib/compact-briefing.js +10 -13
- package/dist/lib/compact-briefing.js.map +1 -1
- package/dist/lib/config-defaults.d.ts.map +1 -1
- package/dist/lib/config-defaults.js +3 -0
- package/dist/lib/config-defaults.js.map +1 -1
- package/dist/lib/config-display.d.ts +4 -0
- package/dist/lib/config-display.d.ts.map +1 -1
- package/dist/lib/config-display.js +6 -1
- package/dist/lib/config-display.js.map +1 -1
- package/dist/lib/config-types.d.ts +149 -0
- package/dist/lib/config-types.d.ts.map +1 -1
- package/dist/lib/config-validation.d.ts.map +1 -1
- package/dist/lib/config-validation.js +5 -0
- package/dist/lib/config-validation.js.map +1 -1
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +92 -9
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/consolidate.d.ts.map +1 -1
- package/dist/lib/consolidate.js +66 -47
- package/dist/lib/consolidate.js.map +1 -1
- package/dist/lib/content-sanitizer.d.ts +29 -0
- package/dist/lib/content-sanitizer.d.ts.map +1 -0
- package/dist/lib/content-sanitizer.js +72 -0
- package/dist/lib/content-sanitizer.js.map +1 -0
- package/dist/lib/cross-repo.d.ts +44 -0
- package/dist/lib/cross-repo.d.ts.map +1 -0
- package/dist/lib/cross-repo.js +108 -0
- package/dist/lib/cross-repo.js.map +1 -0
- package/dist/lib/daemon-port.d.ts +12 -0
- package/dist/lib/daemon-port.d.ts.map +1 -0
- package/dist/lib/daemon-port.js +20 -0
- package/dist/lib/daemon-port.js.map +1 -0
- package/dist/lib/db/auto-memory.d.ts +40 -0
- package/dist/lib/db/auto-memory.d.ts.map +1 -0
- package/dist/lib/db/auto-memory.js +74 -0
- package/dist/lib/db/auto-memory.js.map +1 -0
- package/dist/lib/db/bm25-indexes.d.ts.map +1 -1
- package/dist/lib/db/bm25-indexes.js +16 -4
- package/dist/lib/db/bm25-indexes.js.map +1 -1
- package/dist/lib/db/documents.d.ts.map +1 -1
- package/dist/lib/db/documents.js +4 -1
- package/dist/lib/db/documents.js.map +1 -1
- package/dist/lib/db/global-memories.d.ts +2 -10
- package/dist/lib/db/global-memories.d.ts.map +1 -1
- package/dist/lib/db/global-memories.js +13 -6
- package/dist/lib/db/global-memories.js.map +1 -1
- package/dist/lib/db/graph.d.ts +5 -1
- package/dist/lib/db/graph.d.ts.map +1 -1
- package/dist/lib/db/graph.js +38 -8
- package/dist/lib/db/graph.js.map +1 -1
- package/dist/lib/db/hybrid-search.d.ts +4 -2
- package/dist/lib/db/hybrid-search.d.ts.map +1 -1
- package/dist/lib/db/hybrid-search.js +29 -11
- package/dist/lib/db/hybrid-search.js.map +1 -1
- package/dist/lib/db/index.d.ts +6 -1
- package/dist/lib/db/index.d.ts.map +1 -1
- package/dist/lib/db/index.js +5 -1
- package/dist/lib/db/index.js.map +1 -1
- package/dist/lib/db/memories.d.ts +19 -14
- package/dist/lib/db/memories.d.ts.map +1 -1
- package/dist/lib/db/memories.js +100 -37
- package/dist/lib/db/memories.js.map +1 -1
- package/dist/lib/db/parse-helpers.d.ts +14 -0
- package/dist/lib/db/parse-helpers.d.ts.map +1 -0
- package/dist/lib/db/parse-helpers.js +59 -0
- package/dist/lib/db/parse-helpers.js.map +1 -0
- package/dist/lib/db/recall-events.d.ts +49 -0
- package/dist/lib/db/recall-events.d.ts.map +1 -0
- package/dist/lib/db/recall-events.js +196 -0
- package/dist/lib/db/recall-events.js.map +1 -0
- package/dist/lib/db/retention.d.ts +4 -3
- package/dist/lib/db/retention.d.ts.map +1 -1
- package/dist/lib/db/retention.js +12 -1
- package/dist/lib/db/retention.js.map +1 -1
- package/dist/lib/db/schema.d.ts +2 -0
- package/dist/lib/db/schema.d.ts.map +1 -1
- package/dist/lib/db/schema.js +140 -80
- package/dist/lib/db/schema.js.map +1 -1
- package/dist/lib/db/skills.d.ts.map +1 -1
- package/dist/lib/db/skills.js +10 -6
- package/dist/lib/db/skills.js.map +1 -1
- package/dist/lib/diff-brain.d.ts +24 -0
- package/dist/lib/diff-brain.d.ts.map +1 -0
- package/dist/lib/diff-brain.js +114 -0
- package/dist/lib/diff-brain.js.map +1 -0
- package/dist/lib/diff-parser.d.ts +74 -0
- package/dist/lib/diff-parser.d.ts.map +1 -0
- package/dist/lib/diff-parser.js +200 -0
- package/dist/lib/diff-parser.js.map +1 -0
- package/dist/lib/embedding-pool.d.ts.map +1 -1
- package/dist/lib/embedding-pool.js +5 -1
- package/dist/lib/embedding-pool.js.map +1 -1
- package/dist/lib/embeddings.d.ts +12 -0
- package/dist/lib/embeddings.d.ts.map +1 -1
- package/dist/lib/embeddings.js +77 -19
- package/dist/lib/embeddings.js.map +1 -1
- package/dist/lib/errors.d.ts +2 -0
- package/dist/lib/errors.d.ts.map +1 -1
- package/dist/lib/errors.js +4 -0
- package/dist/lib/errors.js.map +1 -1
- package/dist/lib/fault-logger.d.ts.map +1 -1
- package/dist/lib/fault-logger.js +22 -7
- package/dist/lib/fault-logger.js.map +1 -1
- package/dist/lib/git/co-change.d.ts +39 -0
- package/dist/lib/git/co-change.d.ts.map +1 -0
- package/dist/lib/git/co-change.js +139 -0
- package/dist/lib/git/co-change.js.map +1 -0
- package/dist/lib/graph/bridge-edges.d.ts +93 -0
- package/dist/lib/graph/bridge-edges.d.ts.map +1 -0
- package/dist/lib/graph/bridge-edges.js +276 -0
- package/dist/lib/graph/bridge-edges.js.map +1 -0
- package/dist/lib/graph/centrality.d.ts +11 -0
- package/dist/lib/graph/centrality.d.ts.map +1 -1
- package/dist/lib/graph/centrality.js +51 -3
- package/dist/lib/graph/centrality.js.map +1 -1
- package/dist/lib/graph/cleanup.d.ts.map +1 -1
- package/dist/lib/graph/cleanup.js +2 -1
- package/dist/lib/graph/cleanup.js.map +1 -1
- package/dist/lib/graph/community-detection.d.ts +17 -2
- package/dist/lib/graph/community-detection.d.ts.map +1 -1
- package/dist/lib/graph/community-detection.js +147 -48
- package/dist/lib/graph/community-detection.js.map +1 -1
- package/dist/lib/graph/community-summaries.d.ts +26 -0
- package/dist/lib/graph/community-summaries.d.ts.map +1 -0
- package/dist/lib/graph/community-summaries.js +130 -0
- package/dist/lib/graph/community-summaries.js.map +1 -0
- package/dist/lib/graph/contextual-proximity.d.ts.map +1 -1
- package/dist/lib/graph/contextual-proximity.js +11 -4
- package/dist/lib/graph/contextual-proximity.js.map +1 -1
- package/dist/lib/graph/graphology-bridge.d.ts +101 -0
- package/dist/lib/graph/graphology-bridge.d.ts.map +1 -0
- package/dist/lib/graph/graphology-bridge.js +488 -0
- package/dist/lib/graph/graphology-bridge.js.map +1 -0
- package/dist/lib/graph/llm-relations.d.ts.map +1 -1
- package/dist/lib/graph/llm-relations.js +27 -5
- package/dist/lib/graph/llm-relations.js.map +1 -1
- package/dist/lib/graph-export.d.ts.map +1 -1
- package/dist/lib/graph-export.js +2 -2
- package/dist/lib/graph-export.js.map +1 -1
- package/dist/lib/graph-scheduler.d.ts +0 -5
- package/dist/lib/graph-scheduler.d.ts.map +1 -1
- package/dist/lib/graph-scheduler.js +5 -1
- package/dist/lib/graph-scheduler.js.map +1 -1
- package/dist/lib/guardrails.d.ts +50 -0
- package/dist/lib/guardrails.d.ts.map +1 -0
- package/dist/lib/guardrails.js +502 -0
- package/dist/lib/guardrails.js.map +1 -0
- package/dist/lib/hook-rules.d.ts +1 -1
- package/dist/lib/hook-rules.d.ts.map +1 -1
- package/dist/lib/hook-rules.js +8 -2
- package/dist/lib/hook-rules.js.map +1 -1
- package/dist/lib/ifc/file-labels.d.ts +35 -0
- package/dist/lib/ifc/file-labels.d.ts.map +1 -0
- package/dist/lib/ifc/file-labels.js +208 -0
- package/dist/lib/ifc/file-labels.js.map +1 -0
- package/dist/lib/ifc/label.d.ts +38 -0
- package/dist/lib/ifc/label.d.ts.map +1 -0
- package/dist/lib/ifc/label.js +80 -0
- package/dist/lib/ifc/label.js.map +1 -0
- package/dist/lib/ifc/session-ifc.d.ts +92 -0
- package/dist/lib/ifc/session-ifc.d.ts.map +1 -0
- package/dist/lib/ifc/session-ifc.js +222 -0
- package/dist/lib/ifc/session-ifc.js.map +1 -0
- package/dist/lib/indexer.js +2 -2
- package/dist/lib/indexer.js.map +1 -1
- package/dist/lib/injection-detector.d.ts +83 -0
- package/dist/lib/injection-detector.d.ts.map +1 -0
- package/dist/lib/injection-detector.js +586 -0
- package/dist/lib/injection-detector.js.map +1 -0
- package/dist/lib/injection-semantic.d.ts +31 -0
- package/dist/lib/injection-semantic.d.ts.map +1 -0
- package/dist/lib/injection-semantic.js +230 -0
- package/dist/lib/injection-semantic.js.map +1 -0
- package/dist/lib/llm.d.ts.map +1 -1
- package/dist/lib/llm.js +19 -4
- package/dist/lib/llm.js.map +1 -1
- package/dist/lib/lock.d.ts.map +1 -1
- package/dist/lib/lock.js +24 -3
- package/dist/lib/lock.js.map +1 -1
- package/dist/lib/md-fetch.d.ts.map +1 -1
- package/dist/lib/md-fetch.js +9 -2
- package/dist/lib/md-fetch.js.map +1 -1
- package/dist/lib/observability.d.ts +75 -0
- package/dist/lib/observability.d.ts.map +1 -0
- package/dist/lib/observability.js +201 -0
- package/dist/lib/observability.js.map +1 -0
- package/dist/lib/ort-session.d.ts +26 -0
- package/dist/lib/ort-session.d.ts.map +1 -1
- package/dist/lib/ort-session.js +107 -3
- package/dist/lib/ort-session.js.map +1 -1
- package/dist/lib/prd/codebase-context.d.ts.map +1 -1
- package/dist/lib/prd/codebase-context.js +9 -2
- package/dist/lib/prd/codebase-context.js.map +1 -1
- package/dist/lib/prd/context.d.ts.map +1 -1
- package/dist/lib/prd/context.js +11 -3
- package/dist/lib/prd/context.js.map +1 -1
- package/dist/lib/prd/export.js +1 -1
- package/dist/lib/prd/export.js.map +1 -1
- package/dist/lib/prd/generate.d.ts.map +1 -1
- package/dist/lib/prd/generate.js +17 -4
- package/dist/lib/prd/generate.js.map +1 -1
- package/dist/lib/prd/parse.d.ts.map +1 -1
- package/dist/lib/prd/parse.js +6 -1
- package/dist/lib/prd/parse.js.map +1 -1
- package/dist/lib/prd/runner.d.ts +1 -2
- package/dist/lib/prd/runner.d.ts.map +1 -1
- package/dist/lib/prd/runner.js +43 -32
- package/dist/lib/prd/runner.js.map +1 -1
- package/dist/lib/prd/worktree.d.ts +1 -2
- package/dist/lib/prd/worktree.d.ts.map +1 -1
- package/dist/lib/prd/worktree.js +62 -70
- package/dist/lib/prd/worktree.js.map +1 -1
- package/dist/lib/precompute-context.d.ts.map +1 -1
- package/dist/lib/precompute-context.js +15 -34
- package/dist/lib/precompute-context.js.map +1 -1
- package/dist/lib/pricing.d.ts.map +1 -1
- package/dist/lib/pricing.js +5 -1
- package/dist/lib/pricing.js.map +1 -1
- package/dist/lib/process-registry.js +3 -3
- package/dist/lib/process-registry.js.map +1 -1
- package/dist/lib/public-api.d.ts +41 -1
- package/dist/lib/public-api.d.ts.map +1 -1
- package/dist/lib/public-api.js +38 -0
- package/dist/lib/public-api.js.map +1 -1
- package/dist/lib/quality.d.ts.map +1 -1
- package/dist/lib/quality.js +15 -6
- package/dist/lib/quality.js.map +1 -1
- package/dist/lib/query-expansion.d.ts +32 -0
- package/dist/lib/query-expansion.d.ts.map +1 -1
- package/dist/lib/query-expansion.js +62 -1
- package/dist/lib/query-expansion.js.map +1 -1
- package/dist/lib/reference-embeddings.d.ts.map +1 -1
- package/dist/lib/reference-embeddings.js +17 -4
- package/dist/lib/reference-embeddings.js.map +1 -1
- package/dist/lib/reflection-synthesizer.d.ts.map +1 -1
- package/dist/lib/reflection-synthesizer.js +7 -1
- package/dist/lib/reflection-synthesizer.js.map +1 -1
- package/dist/lib/reranker.d.ts +41 -0
- package/dist/lib/reranker.d.ts.map +1 -0
- package/dist/lib/reranker.js +294 -0
- package/dist/lib/reranker.js.map +1 -0
- package/dist/lib/retrieval-feedback.d.ts +100 -0
- package/dist/lib/retrieval-feedback.d.ts.map +1 -0
- package/dist/lib/retrieval-feedback.js +174 -0
- package/dist/lib/retrieval-feedback.js.map +1 -0
- package/dist/lib/review/context-pack.d.ts +58 -0
- package/dist/lib/review/context-pack.d.ts.map +1 -0
- package/dist/lib/review/context-pack.js +300 -0
- package/dist/lib/review/context-pack.js.map +1 -0
- package/dist/lib/search/hierarchical-summaries.d.ts +65 -0
- package/dist/lib/search/hierarchical-summaries.d.ts.map +1 -0
- package/dist/lib/search/hierarchical-summaries.js +423 -0
- package/dist/lib/search/hierarchical-summaries.js.map +1 -0
- package/dist/lib/search/hyde.d.ts +27 -0
- package/dist/lib/search/hyde.d.ts.map +1 -0
- package/dist/lib/search/hyde.js +141 -0
- package/dist/lib/search/hyde.js.map +1 -0
- package/dist/lib/search/late-chunking.d.ts +53 -0
- package/dist/lib/search/late-chunking.d.ts.map +1 -0
- package/dist/lib/search/late-chunking.js +230 -0
- package/dist/lib/search/late-chunking.js.map +1 -0
- package/dist/lib/search/ppr-retrieval.d.ts +49 -0
- package/dist/lib/search/ppr-retrieval.d.ts.map +1 -0
- package/dist/lib/search/ppr-retrieval.js +135 -0
- package/dist/lib/search/ppr-retrieval.js.map +1 -0
- package/dist/lib/search/repo-map.d.ts +43 -0
- package/dist/lib/search/repo-map.d.ts.map +1 -0
- package/dist/lib/search/repo-map.js +165 -0
- package/dist/lib/search/repo-map.js.map +1 -0
- package/dist/lib/session-analyzer.d.ts +90 -0
- package/dist/lib/session-analyzer.d.ts.map +1 -0
- package/dist/lib/session-analyzer.js +467 -0
- package/dist/lib/session-analyzer.js.map +1 -0
- package/dist/lib/session-observations.d.ts.map +1 -1
- package/dist/lib/session-observations.js +13 -3
- package/dist/lib/session-observations.js.map +1 -1
- package/dist/lib/session-summary.d.ts.map +1 -1
- package/dist/lib/session-summary.js +57 -50
- package/dist/lib/session-summary.js.map +1 -1
- package/dist/lib/session-surgeon.d.ts +53 -0
- package/dist/lib/session-surgeon.d.ts.map +1 -0
- package/dist/lib/session-surgeon.js +501 -0
- package/dist/lib/session-surgeon.js.map +1 -0
- package/dist/lib/similarity-utils.d.ts +26 -0
- package/dist/lib/similarity-utils.d.ts.map +1 -0
- package/dist/lib/similarity-utils.js +66 -0
- package/dist/lib/similarity-utils.js.map +1 -0
- package/dist/lib/skills.d.ts.map +1 -1
- package/dist/lib/skills.js +11 -11
- package/dist/lib/skills.js.map +1 -1
- package/dist/lib/storage/backends/interface.d.ts +13 -3
- package/dist/lib/storage/backends/interface.d.ts.map +1 -1
- package/dist/lib/storage/backends/postgresql.d.ts +52 -3
- package/dist/lib/storage/backends/postgresql.d.ts.map +1 -1
- package/dist/lib/storage/backends/postgresql.js +694 -49
- package/dist/lib/storage/backends/postgresql.js.map +1 -1
- package/dist/lib/storage/benchmark.js +2 -2
- package/dist/lib/storage/benchmark.js.map +1 -1
- package/dist/lib/storage/dispatcher/base.d.ts +114 -0
- package/dist/lib/storage/dispatcher/base.d.ts.map +1 -0
- package/dist/lib/storage/dispatcher/base.js +160 -0
- package/dist/lib/storage/dispatcher/base.js.map +1 -0
- package/dist/lib/storage/dispatcher/documents.d.ts +25 -0
- package/dist/lib/storage/dispatcher/documents.d.ts.map +1 -0
- package/dist/lib/storage/dispatcher/documents.js +194 -0
- package/dist/lib/storage/dispatcher/documents.js.map +1 -0
- package/dist/lib/storage/dispatcher/embeddings.d.ts +34 -0
- package/dist/lib/storage/dispatcher/embeddings.d.ts.map +1 -0
- package/dist/lib/storage/dispatcher/embeddings.js +144 -0
- package/dist/lib/storage/dispatcher/embeddings.js.map +1 -0
- package/dist/lib/storage/dispatcher/export-import.d.ts +139 -0
- package/dist/lib/storage/dispatcher/export-import.d.ts.map +1 -0
- package/dist/lib/storage/dispatcher/export-import.js +191 -0
- package/dist/lib/storage/dispatcher/export-import.js.map +1 -0
- package/dist/lib/storage/dispatcher/file-hashes.d.ts +13 -0
- package/dist/lib/storage/dispatcher/file-hashes.d.ts.map +1 -0
- package/dist/lib/storage/dispatcher/file-hashes.js +36 -0
- package/dist/lib/storage/dispatcher/file-hashes.js.map +1 -0
- package/dist/lib/storage/dispatcher/global-memories.d.ts +28 -0
- package/dist/lib/storage/dispatcher/global-memories.d.ts.map +1 -0
- package/dist/lib/storage/dispatcher/global-memories.js +151 -0
- package/dist/lib/storage/dispatcher/global-memories.js.map +1 -0
- package/dist/lib/storage/dispatcher/graph.d.ts +32 -0
- package/dist/lib/storage/dispatcher/graph.d.ts.map +1 -0
- package/dist/lib/storage/dispatcher/graph.js +146 -0
- package/dist/lib/storage/dispatcher/graph.js.map +1 -0
- package/dist/lib/storage/dispatcher/index.d.ts +34 -0
- package/dist/lib/storage/dispatcher/index.d.ts.map +1 -0
- package/dist/lib/storage/dispatcher/index.js +139 -0
- package/dist/lib/storage/dispatcher/index.js.map +1 -0
- package/dist/lib/storage/dispatcher/memories.d.ts +65 -0
- package/dist/lib/storage/dispatcher/memories.d.ts.map +1 -0
- package/dist/lib/storage/dispatcher/memories.js +466 -0
- package/dist/lib/storage/dispatcher/memories.js.map +1 -0
- package/dist/lib/storage/dispatcher/mixin-helper.d.ts +6 -0
- package/dist/lib/storage/dispatcher/mixin-helper.d.ts.map +1 -0
- package/dist/lib/storage/dispatcher/mixin-helper.js +10 -0
- package/dist/lib/storage/dispatcher/mixin-helper.js.map +1 -0
- package/dist/lib/storage/dispatcher/retention.d.ts +20 -0
- package/dist/lib/storage/dispatcher/retention.d.ts.map +1 -0
- package/dist/lib/storage/dispatcher/retention.js +123 -0
- package/dist/lib/storage/dispatcher/retention.js.map +1 -0
- package/dist/lib/storage/dispatcher/search.d.ts +34 -0
- package/dist/lib/storage/dispatcher/search.d.ts.map +1 -0
- package/dist/lib/storage/dispatcher/search.js +222 -0
- package/dist/lib/storage/dispatcher/search.js.map +1 -0
- package/dist/lib/storage/dispatcher/skills.d.ts +53 -0
- package/dist/lib/storage/dispatcher/skills.d.ts.map +1 -0
- package/dist/lib/storage/dispatcher/skills.js +98 -0
- package/dist/lib/storage/dispatcher/skills.js.map +1 -0
- package/dist/lib/storage/dispatcher/token-stats.d.ts +23 -0
- package/dist/lib/storage/dispatcher/token-stats.d.ts.map +1 -0
- package/dist/lib/storage/dispatcher/token-stats.js +92 -0
- package/dist/lib/storage/dispatcher/token-stats.js.map +1 -0
- package/dist/lib/storage/dispatcher/web-search.d.ts +10 -0
- package/dist/lib/storage/dispatcher/web-search.d.ts.map +1 -0
- package/dist/lib/storage/dispatcher/web-search.js +39 -0
- package/dist/lib/storage/dispatcher/web-search.js.map +1 -0
- package/dist/lib/storage/dispatcher-export.d.ts.map +1 -1
- package/dist/lib/storage/dispatcher-export.js +48 -39
- package/dist/lib/storage/dispatcher-export.js.map +1 -1
- package/dist/lib/storage/dispatcher.d.ts +1 -468
- package/dist/lib/storage/dispatcher.d.ts.map +1 -1
- package/dist/lib/storage/dispatcher.js +1 -1931
- package/dist/lib/storage/dispatcher.js.map +1 -1
- package/dist/lib/storage/index.d.ts +20 -5
- package/dist/lib/storage/index.d.ts.map +1 -1
- package/dist/lib/storage/index.js +36 -7
- package/dist/lib/storage/index.js.map +1 -1
- package/dist/lib/storage/migration/export-import.d.ts.map +1 -1
- package/dist/lib/storage/migration/export-import.js +9 -2
- package/dist/lib/storage/migration/export-import.js.map +1 -1
- package/dist/lib/storage/types.d.ts +152 -10
- package/dist/lib/storage/types.d.ts.map +1 -1
- package/dist/lib/storage/types.js +13 -0
- package/dist/lib/storage/types.js.map +1 -1
- package/dist/lib/storage/vector/interface.d.ts +4 -0
- package/dist/lib/storage/vector/interface.d.ts.map +1 -1
- package/dist/lib/storage/vector/qdrant.d.ts +13 -2
- package/dist/lib/storage/vector/qdrant.d.ts.map +1 -1
- package/dist/lib/storage/vector/qdrant.js +147 -61
- package/dist/lib/storage/vector/qdrant.js.map +1 -1
- package/dist/lib/token-budget.d.ts.map +1 -1
- package/dist/lib/token-budget.js +9 -2
- package/dist/lib/token-budget.js.map +1 -1
- package/dist/lib/transcript-utils.d.ts +60 -0
- package/dist/lib/transcript-utils.d.ts.map +1 -0
- package/dist/lib/transcript-utils.js +69 -0
- package/dist/lib/transcript-utils.js.map +1 -0
- package/dist/lib/tree-sitter/extractor.d.ts +1 -1
- package/dist/lib/tree-sitter/extractor.d.ts.map +1 -1
- package/dist/lib/tree-sitter/extractor.js +34 -9
- package/dist/lib/tree-sitter/extractor.js.map +1 -1
- package/dist/lib/tree-sitter/parser.d.ts.map +1 -1
- package/dist/lib/tree-sitter/parser.js +45 -11
- package/dist/lib/tree-sitter/parser.js.map +1 -1
- package/dist/lib/tree-sitter/public.d.ts +12 -0
- package/dist/lib/tree-sitter/public.d.ts.map +1 -1
- package/dist/lib/tree-sitter/public.js +33 -1
- package/dist/lib/tree-sitter/public.js.map +1 -1
- package/dist/lib/tree-sitter/queries.d.ts.map +1 -1
- package/dist/lib/tree-sitter/queries.js +8 -0
- package/dist/lib/tree-sitter/queries.js.map +1 -1
- package/dist/lib/working-memory-pipeline.d.ts.map +1 -1
- package/dist/lib/working-memory-pipeline.js +12 -3
- package/dist/lib/working-memory-pipeline.js.map +1 -1
- package/dist/lib/worktree-detect.d.ts +43 -0
- package/dist/lib/worktree-detect.d.ts.map +1 -0
- package/dist/lib/worktree-detect.js +154 -0
- package/dist/lib/worktree-detect.js.map +1 -0
- package/dist/lsp/client.d.ts +96 -0
- package/dist/lsp/client.d.ts.map +1 -0
- package/dist/lsp/client.js +435 -0
- package/dist/lsp/client.js.map +1 -0
- package/dist/lsp/installer.d.ts +39 -0
- package/dist/lsp/installer.d.ts.map +1 -0
- package/dist/lsp/installer.js +275 -0
- package/dist/lsp/installer.js.map +1 -0
- package/dist/lsp/manager.d.ts +62 -0
- package/dist/lsp/manager.d.ts.map +1 -0
- package/dist/lsp/manager.js +234 -0
- package/dist/lsp/manager.js.map +1 -0
- package/dist/lsp/servers.d.ts +52 -0
- package/dist/lsp/servers.d.ts.map +1 -0
- package/dist/lsp/servers.js +162 -0
- package/dist/lsp/servers.js.map +1 -0
- package/dist/mcp/helpers.d.ts.map +1 -1
- package/dist/mcp/helpers.js +8 -2
- package/dist/mcp/helpers.js.map +1 -1
- package/dist/mcp/profile.js +1 -1
- package/dist/mcp/server.d.ts +3 -2
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +19 -7
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools/config.d.ts.map +1 -1
- package/dist/mcp/tools/config.js +28 -118
- package/dist/mcp/tools/config.js.map +1 -1
- package/dist/mcp/tools/dead-end.d.ts.map +1 -1
- package/dist/mcp/tools/dead-end.js +4 -3
- package/dist/mcp/tools/dead-end.js.map +1 -1
- package/dist/mcp/tools/debug.d.ts.map +1 -1
- package/dist/mcp/tools/debug.js +27 -112
- package/dist/mcp/tools/debug.js.map +1 -1
- package/dist/mcp/tools/graph.d.ts.map +1 -1
- package/dist/mcp/tools/graph.js +164 -176
- package/dist/mcp/tools/graph.js.map +1 -1
- package/dist/mcp/tools/indexing.d.ts +1 -1
- package/dist/mcp/tools/indexing.d.ts.map +1 -1
- package/dist/mcp/tools/indexing.js +63 -164
- package/dist/mcp/tools/indexing.js.map +1 -1
- package/dist/mcp/tools/memory/forget.d.ts +3 -0
- package/dist/mcp/tools/memory/forget.d.ts.map +1 -0
- package/dist/mcp/tools/memory/forget.js +175 -0
- package/dist/mcp/tools/memory/forget.js.map +1 -0
- package/dist/mcp/tools/memory/memory-helpers.d.ts +45 -0
- package/dist/mcp/tools/memory/memory-helpers.d.ts.map +1 -0
- package/dist/mcp/tools/memory/memory-helpers.js +291 -0
- package/dist/mcp/tools/memory/memory-helpers.js.map +1 -0
- package/dist/mcp/tools/memory/recall.d.ts +3 -0
- package/dist/mcp/tools/memory/recall.d.ts.map +1 -0
- package/dist/mcp/tools/memory/recall.js +495 -0
- package/dist/mcp/tools/memory/recall.js.map +1 -0
- package/dist/mcp/tools/memory/remember.d.ts +3 -0
- package/dist/mcp/tools/memory/remember.d.ts.map +1 -0
- package/dist/mcp/tools/memory/remember.js +256 -0
- package/dist/mcp/tools/memory/remember.js.map +1 -0
- package/dist/mcp/tools/memory/temporal-query.d.ts +8 -0
- package/dist/mcp/tools/memory/temporal-query.d.ts.map +1 -0
- package/dist/mcp/tools/memory/temporal-query.js +68 -0
- package/dist/mcp/tools/memory/temporal-query.js.map +1 -0
- package/dist/mcp/tools/memory.d.ts +0 -11
- package/dist/mcp/tools/memory.d.ts.map +1 -1
- package/dist/mcp/tools/memory.js +6 -1228
- package/dist/mcp/tools/memory.js.map +1 -1
- package/dist/mcp/tools/prd.d.ts.map +1 -1
- package/dist/mcp/tools/prd.js +19 -70
- package/dist/mcp/tools/prd.js.map +1 -1
- package/dist/mcp/tools/review.d.ts +8 -0
- package/dist/mcp/tools/review.d.ts.map +1 -0
- package/dist/mcp/tools/review.js +133 -0
- package/dist/mcp/tools/review.js.map +1 -0
- package/dist/mcp/tools/search.d.ts.map +1 -1
- package/dist/mcp/tools/search.js +79 -8
- package/dist/mcp/tools/search.js.map +1 -1
- package/dist/mcp/tools/status.d.ts.map +1 -1
- package/dist/mcp/tools/status.js +34 -75
- package/dist/mcp/tools/status.js.map +1 -1
- package/dist/mcp/tools/web-fetch.d.ts.map +1 -1
- package/dist/mcp/tools/web-fetch.js +5 -1
- package/dist/mcp/tools/web-fetch.js.map +1 -1
- package/dist/mcp/tools/web-search.d.ts.map +1 -1
- package/dist/mcp/tools/web-search.js +25 -103
- package/dist/mcp/tools/web-search.js.map +1 -1
- package/dist/prompts/guardrails.d.ts +14 -0
- package/dist/prompts/guardrails.d.ts.map +1 -0
- package/dist/prompts/guardrails.js +115 -0
- package/dist/prompts/guardrails.js.map +1 -0
- package/dist/prompts/index.d.ts +2 -1
- package/dist/prompts/index.d.ts.map +1 -1
- package/dist/prompts/index.js +3 -1
- package/dist/prompts/index.js.map +1 -1
- package/dist/prompts/prd.d.ts +0 -2
- package/dist/prompts/prd.d.ts.map +1 -1
- package/dist/prompts/prd.js +0 -2
- package/dist/prompts/prd.js.map +1 -1
- package/hooks/core/__tests__/adapter.test.cjs +340 -0
- package/hooks/core/adapter.cjs +463 -0
- package/hooks/core/config.cjs +83 -0
- package/hooks/core/daemon-boot.cjs +140 -0
- package/hooks/core/log.cjs +41 -0
- package/hooks/core/worktree.cjs +119 -0
- package/hooks/succ-post-tool.cjs +198 -134
- package/hooks/succ-pre-compact.cjs +262 -0
- package/hooks/succ-pre-tool.cjs +526 -182
- package/hooks/succ-session-end.cjs +40 -64
- package/hooks/succ-session-start.cjs +484 -430
- package/hooks/succ-stop-reflection.cjs +36 -62
- package/hooks/succ-user-prompt.cjs +137 -180
- package/package.json +17 -6
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File Label Assignment — 4-layer label resolution for BLP IFC
|
|
3
|
+
*
|
|
4
|
+
* Assigns SecurityLabels to files using conservative (highest wins) layering:
|
|
5
|
+
* 1. Extension-based (deterministic, instant)
|
|
6
|
+
* 2. Path-based (deterministic, instant)
|
|
7
|
+
* 3. Content-based regex (deterministic, requires file content)
|
|
8
|
+
* 4. LLM classification (Phase 3, opt-in)
|
|
9
|
+
*
|
|
10
|
+
* Label assignment is monotonic — higher label always wins.
|
|
11
|
+
*/
|
|
12
|
+
import { makeLabel, join, BOTTOM, } from './label.js';
|
|
13
|
+
const EXTENSION_RULES = [
|
|
14
|
+
// Highly confidential: private keys and certs
|
|
15
|
+
{
|
|
16
|
+
extensions: ['.pem', '.key', '.p12', '.pfx', '.jks', '.keystore'],
|
|
17
|
+
label: makeLabel(3, ['credentials']),
|
|
18
|
+
},
|
|
19
|
+
// Confidential: environment files with secrets
|
|
20
|
+
{
|
|
21
|
+
extensions: ['.env', '.env.local', '.env.production', '.env.staging', '.env.development'],
|
|
22
|
+
label: makeLabel(2, ['secrets', 'credentials']),
|
|
23
|
+
},
|
|
24
|
+
// Internal: config files that may contain infrastructure info
|
|
25
|
+
{
|
|
26
|
+
extensions: ['.htpasswd', '.htaccess'],
|
|
27
|
+
label: makeLabel(2, ['credentials']),
|
|
28
|
+
},
|
|
29
|
+
// Public: documentation
|
|
30
|
+
{
|
|
31
|
+
extensions: ['.md', '.txt', '.rst', '.adoc'],
|
|
32
|
+
label: BOTTOM,
|
|
33
|
+
},
|
|
34
|
+
];
|
|
35
|
+
function labelByExtension(filePath) {
|
|
36
|
+
const lower = filePath.toLowerCase().replace(/\\/g, '/');
|
|
37
|
+
const basename = lower.split('/').pop() || '';
|
|
38
|
+
// Check full basename match first (for .env, .env.local, .env.production, etc.)
|
|
39
|
+
for (const rule of EXTENSION_RULES) {
|
|
40
|
+
for (const ext of rule.extensions) {
|
|
41
|
+
const name = ext.slice(1); // e.g. "env", "env.local", "pem"
|
|
42
|
+
// Exact match: ".env" → basename ".env"
|
|
43
|
+
if (basename === ext || basename === name) {
|
|
44
|
+
return rule.label;
|
|
45
|
+
}
|
|
46
|
+
// Prefix match: ".env" rule matches ".env.production", ".env.staging", etc.
|
|
47
|
+
// But NOT env.sh, env.py, etc. — only .env.* or bare env files
|
|
48
|
+
if (ext === '.env' && basename.startsWith('.env.')) {
|
|
49
|
+
return rule.label;
|
|
50
|
+
}
|
|
51
|
+
// Match bare "env" followed by dot-separated qualifiers (env.local, env.production)
|
|
52
|
+
// but NOT env.sh, env.py, env.ts, etc. (script files)
|
|
53
|
+
if (ext === '.env' && basename.startsWith('env.')) {
|
|
54
|
+
const afterEnvDot = basename.slice(4); // after "env."
|
|
55
|
+
// If it looks like a file extension (2-4 chars, common code ext), skip
|
|
56
|
+
if (/^(?:sh|py|ts|js|rb|go|rs|pl|bat|cmd|ps1|php|java|c|h|cpp)$/i.test(afterEnvDot)) {
|
|
57
|
+
// Not an env config file — skip
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
return rule.label;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// Check all extensions in compound filenames (e.g., "backup.pem.bak" → check ".bak", ".pem")
|
|
66
|
+
// This ensures security-sensitive inner extensions aren't missed when outer extension differs
|
|
67
|
+
let compoundLabel = BOTTOM;
|
|
68
|
+
let remaining = basename;
|
|
69
|
+
while (true) {
|
|
70
|
+
const dotIdx = remaining.lastIndexOf('.');
|
|
71
|
+
if (dotIdx < 0)
|
|
72
|
+
break;
|
|
73
|
+
const ext = remaining.slice(dotIdx);
|
|
74
|
+
for (const rule of EXTENSION_RULES) {
|
|
75
|
+
if (rule.extensions.includes(ext)) {
|
|
76
|
+
compoundLabel = join(compoundLabel, rule.label);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
remaining = remaining.slice(0, dotIdx);
|
|
80
|
+
}
|
|
81
|
+
return compoundLabel;
|
|
82
|
+
}
|
|
83
|
+
const PATH_RULES = [
|
|
84
|
+
// Secrets directories
|
|
85
|
+
{ pattern: /[/\\]secrets?[/\\]/i, label: makeLabel(3, ['secrets']) },
|
|
86
|
+
{ pattern: /[/\\]\.ssh[/\\]/i, label: makeLabel(3, ['credentials']) },
|
|
87
|
+
{ pattern: /[/\\]\.gnupg[/\\]/i, label: makeLabel(3, ['credentials']) },
|
|
88
|
+
{ pattern: /[/\\]private[/\\]/i, label: makeLabel(2, ['credentials']) },
|
|
89
|
+
// Infrastructure
|
|
90
|
+
{ pattern: /[/\\]deploy[/\\]/i, label: makeLabel(2, ['internal_infra']) },
|
|
91
|
+
{ pattern: /[/\\]infrastructure[/\\]/i, label: makeLabel(2, ['internal_infra']) },
|
|
92
|
+
{ pattern: /[/\\]terraform[/\\]/i, label: makeLabel(2, ['internal_infra']) },
|
|
93
|
+
{ pattern: /[/\\]k8s[/\\]/i, label: makeLabel(2, ['internal_infra']) },
|
|
94
|
+
{ pattern: /[/\\]kubernetes[/\\]/i, label: makeLabel(2, ['internal_infra']) },
|
|
95
|
+
{ pattern: /[/\\]ansible[/\\]/i, label: makeLabel(2, ['internal_infra']) },
|
|
96
|
+
// CI/CD configs (may contain deployment secrets)
|
|
97
|
+
{ pattern: /[/\\]\.github[/\\]workflows[/\\]/i, label: makeLabel(1, ['internal_infra']) },
|
|
98
|
+
{ pattern: /[/\\]\.gitlab-ci\.yml$/i, label: makeLabel(1, ['internal_infra']) },
|
|
99
|
+
{ pattern: /[/\\]\.circleci[/\\]/i, label: makeLabel(1, ['internal_infra']) },
|
|
100
|
+
// Skip: node_modules, .git internals — not sensitive per se
|
|
101
|
+
{ pattern: /[/\\]node_modules[/\\]/i, label: BOTTOM },
|
|
102
|
+
{ pattern: /[/\\]\.git[/\\]/i, label: makeLabel(1) },
|
|
103
|
+
];
|
|
104
|
+
function labelByPath(filePath) {
|
|
105
|
+
let normalized = filePath.replace(/\\/g, '/');
|
|
106
|
+
// Ensure repo-relative paths (e.g., "secrets/key.pem") match PATH_RULES that require /dir/ delimiters
|
|
107
|
+
if (!normalized.startsWith('/')) {
|
|
108
|
+
normalized = '/' + normalized;
|
|
109
|
+
}
|
|
110
|
+
let result = BOTTOM;
|
|
111
|
+
for (const rule of PATH_RULES) {
|
|
112
|
+
if (rule.pattern.test(normalized)) {
|
|
113
|
+
result = join(result, rule.label);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return result;
|
|
117
|
+
}
|
|
118
|
+
const CONTENT_PATTERNS = [
|
|
119
|
+
// API keys / tokens (→ secrets)
|
|
120
|
+
{ pattern: /sk-(?:proj-)?[a-zA-Z0-9]{20,}/, compartments: ['secrets'], level: 3 },
|
|
121
|
+
{ pattern: /sk-ant-[a-zA-Z0-9-]{20,}/, compartments: ['secrets'], level: 3 },
|
|
122
|
+
{ pattern: /AKIA[0-9A-Z]{16}/, compartments: ['secrets'], level: 3 },
|
|
123
|
+
{ pattern: /gh[pousr]_[a-zA-Z0-9]{36}/, compartments: ['secrets'], level: 3 },
|
|
124
|
+
{ pattern: /github_pat_[a-zA-Z0-9]{22,}/, compartments: ['secrets'], level: 3 },
|
|
125
|
+
{ pattern: /glpat-[a-zA-Z0-9-]{20,}/, compartments: ['secrets'], level: 3 },
|
|
126
|
+
{
|
|
127
|
+
pattern: /xox[baprs]-[0-9]{10,13}-[0-9]{10,13}-[a-zA-Z0-9]{24}/,
|
|
128
|
+
compartments: ['secrets'],
|
|
129
|
+
level: 3,
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
pattern: /eyJ[a-zA-Z0-9_-]*\.eyJ[a-zA-Z0-9_-]*\.[a-zA-Z0-9_-]*/,
|
|
133
|
+
compartments: ['secrets'],
|
|
134
|
+
level: 2,
|
|
135
|
+
},
|
|
136
|
+
// Private keys (→ credentials)
|
|
137
|
+
{
|
|
138
|
+
pattern: /-----BEGIN (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----/,
|
|
139
|
+
compartments: ['credentials'],
|
|
140
|
+
level: 3,
|
|
141
|
+
},
|
|
142
|
+
// Password assignments (→ secrets)
|
|
143
|
+
{
|
|
144
|
+
pattern: /(?:password|passwd|secret|api_key)\s*[:=]\s*['"][^'"]{8,}['"]/,
|
|
145
|
+
compartments: ['secrets'],
|
|
146
|
+
level: 2,
|
|
147
|
+
},
|
|
148
|
+
// Connection strings (→ credentials + internal_infra)
|
|
149
|
+
{
|
|
150
|
+
pattern: /(?:postgres|mysql|mongodb|redis):\/\/[^:]+:[^@]+@/,
|
|
151
|
+
compartments: ['credentials', 'internal_infra'],
|
|
152
|
+
level: 2,
|
|
153
|
+
},
|
|
154
|
+
// PII patterns
|
|
155
|
+
{ pattern: /\b\d{3}-\d{2}-\d{4}\b/, compartments: ['pii'], level: 2 }, // SSN
|
|
156
|
+
{ pattern: /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z]{2,}\b/i, compartments: ['pii'], level: 1 }, // Email (low level — very common)
|
|
157
|
+
// Internal infrastructure markers
|
|
158
|
+
{
|
|
159
|
+
pattern: /(?:10\.\d{1,3}\.\d{1,3}\.\d{1,3}|172\.(?:1[6-9]|2\d|3[01])\.\d{1,3}\.\d{1,3}|192\.168\.\d{1,3}\.\d{1,3})/,
|
|
160
|
+
compartments: ['internal_infra'],
|
|
161
|
+
level: 1,
|
|
162
|
+
},
|
|
163
|
+
];
|
|
164
|
+
/**
|
|
165
|
+
* Scan file content for sensitive patterns and return accumulated label.
|
|
166
|
+
* Short-circuits if content is empty.
|
|
167
|
+
*/
|
|
168
|
+
export function labelByContent(content) {
|
|
169
|
+
if (!content || content.length === 0)
|
|
170
|
+
return BOTTOM;
|
|
171
|
+
let result = BOTTOM;
|
|
172
|
+
for (const { pattern, compartments, level } of CONTENT_PATTERNS) {
|
|
173
|
+
if (pattern.test(content)) {
|
|
174
|
+
result = join(result, makeLabel(level, compartments));
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return result;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Resolve the security label for a file using 3 deterministic layers.
|
|
181
|
+
* Returns the join (LUB) of all applicable labels.
|
|
182
|
+
*
|
|
183
|
+
* Layer 4 (LLM classification) is handled externally in Phase 3.
|
|
184
|
+
*/
|
|
185
|
+
export function resolveFileLabel(filePath, options = {}) {
|
|
186
|
+
// Normalize relative paths to have path separators for path-based rules
|
|
187
|
+
const normalizedPath = filePath.includes('/') || filePath.includes('\\') ? filePath : './' + filePath;
|
|
188
|
+
let result = BOTTOM;
|
|
189
|
+
// Layer 1: Extension
|
|
190
|
+
result = join(result, labelByExtension(normalizedPath));
|
|
191
|
+
// Layer 2: Path
|
|
192
|
+
result = join(result, labelByPath(normalizedPath));
|
|
193
|
+
// Layer 3: Content (if provided)
|
|
194
|
+
if (options.content) {
|
|
195
|
+
result = join(result, labelByContent(options.content));
|
|
196
|
+
}
|
|
197
|
+
return result;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Quick label check — extension + path only (no content scan).
|
|
201
|
+
* Use for pre-tool checks where content isn't available yet.
|
|
202
|
+
*/
|
|
203
|
+
export function quickFileLabel(filePath) {
|
|
204
|
+
return join(labelByExtension(filePath), labelByPath(filePath));
|
|
205
|
+
}
|
|
206
|
+
// Re-export for convenience
|
|
207
|
+
export { BOTTOM, makeLabel, join, isBottom, } from './label.js';
|
|
208
|
+
//# sourceMappingURL=file-labels.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-labels.js","sourceRoot":"","sources":["../../../src/lib/ifc/file-labels.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bell-LaPadula Security Label Lattice
|
|
3
|
+
*
|
|
4
|
+
* Full BLP model with compartments:
|
|
5
|
+
* - SecurityLevel: 0=public, 1=internal, 2=confidential, 3=highly_confidential
|
|
6
|
+
* - Compartments: secrets, credentials, pii, internal_infra
|
|
7
|
+
* - Lattice operations: join (LUB), dominates, isBottom, isComparable
|
|
8
|
+
*
|
|
9
|
+
* Label rules:
|
|
10
|
+
* - Labels only go UP (weak tranquility)
|
|
11
|
+
* - join(a, b) = max level + union compartments
|
|
12
|
+
* - dominates(a, b) = a.level >= b.level AND a.compartments ⊇ b.compartments
|
|
13
|
+
*/
|
|
14
|
+
export type SecurityLevel = 0 | 1 | 2 | 3;
|
|
15
|
+
export declare const LEVEL_NAMES: Record<SecurityLevel, string>;
|
|
16
|
+
export type Compartment = 'secrets' | 'credentials' | 'pii' | 'internal_infra';
|
|
17
|
+
export declare const ALL_COMPARTMENTS: readonly Compartment[];
|
|
18
|
+
export interface SecurityLabel {
|
|
19
|
+
readonly level: SecurityLevel;
|
|
20
|
+
readonly compartments: ReadonlySet<Compartment>;
|
|
21
|
+
}
|
|
22
|
+
/** The bottom of the lattice — no classification, no compartments */
|
|
23
|
+
export declare const BOTTOM: SecurityLabel;
|
|
24
|
+
/** Create a label */
|
|
25
|
+
export declare function makeLabel(level: SecurityLevel, compartments?: Compartment[]): SecurityLabel;
|
|
26
|
+
/** Least Upper Bound — max level, union of compartments */
|
|
27
|
+
export declare function join(a: SecurityLabel, b: SecurityLabel): SecurityLabel;
|
|
28
|
+
/** Does `a` dominate `b`? (a.level >= b.level AND a.compartments ⊇ b.compartments) */
|
|
29
|
+
export declare function dominates(a: SecurityLabel, b: SecurityLabel): boolean;
|
|
30
|
+
/** Is label at the bottom of the lattice? */
|
|
31
|
+
export declare function isBottom(label: SecurityLabel): boolean;
|
|
32
|
+
/** Are two labels comparable? (one dominates the other) */
|
|
33
|
+
export declare function isComparable(a: SecurityLabel, b: SecurityLabel): boolean;
|
|
34
|
+
/** Are two labels equal? */
|
|
35
|
+
export declare function labelsEqual(a: SecurityLabel, b: SecurityLabel): boolean;
|
|
36
|
+
/** Format label for display */
|
|
37
|
+
export declare function formatLabel(label: SecurityLabel): string;
|
|
38
|
+
//# sourceMappingURL=label.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"label.d.ts","sourceRoot":"","sources":["../../../src/lib/ifc/label.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAE1C,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAKrD,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,aAAa,GAAG,KAAK,GAAG,gBAAgB,CAAC;AAE/E,eAAO,MAAM,gBAAgB,EAAE,SAAS,WAAW,EAKzC,CAAC;AAEX,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC;CACjD;AAED,qEAAqE;AACrE,eAAO,MAAM,MAAM,EAAE,aAGF,CAAC;AAEpB,qBAAqB;AACrB,wBAAgB,SAAS,CAAC,KAAK,EAAE,aAAa,EAAE,YAAY,GAAE,WAAW,EAAO,GAAG,aAAa,CAK/F;AAED,2DAA2D;AAC3D,wBAAgB,IAAI,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,aAAa,GAAG,aAAa,CAItE;AAED,sFAAsF;AACtF,wBAAgB,SAAS,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,aAAa,GAAG,OAAO,CAMrE;AAED,6CAA6C;AAC7C,wBAAgB,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAEtD;AAED,2DAA2D;AAC3D,wBAAgB,YAAY,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,aAAa,GAAG,OAAO,CAExE;AAED,4BAA4B;AAC5B,wBAAgB,WAAW,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,aAAa,GAAG,OAAO,CAOvE;AAED,+BAA+B;AAC/B,wBAAgB,WAAW,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAIxD"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bell-LaPadula Security Label Lattice
|
|
3
|
+
*
|
|
4
|
+
* Full BLP model with compartments:
|
|
5
|
+
* - SecurityLevel: 0=public, 1=internal, 2=confidential, 3=highly_confidential
|
|
6
|
+
* - Compartments: secrets, credentials, pii, internal_infra
|
|
7
|
+
* - Lattice operations: join (LUB), dominates, isBottom, isComparable
|
|
8
|
+
*
|
|
9
|
+
* Label rules:
|
|
10
|
+
* - Labels only go UP (weak tranquility)
|
|
11
|
+
* - join(a, b) = max level + union compartments
|
|
12
|
+
* - dominates(a, b) = a.level >= b.level AND a.compartments ⊇ b.compartments
|
|
13
|
+
*/
|
|
14
|
+
export const LEVEL_NAMES = {
|
|
15
|
+
0: 'public',
|
|
16
|
+
1: 'internal',
|
|
17
|
+
2: 'confidential',
|
|
18
|
+
3: 'highly_confidential',
|
|
19
|
+
};
|
|
20
|
+
export const ALL_COMPARTMENTS = [
|
|
21
|
+
'secrets',
|
|
22
|
+
'credentials',
|
|
23
|
+
'pii',
|
|
24
|
+
'internal_infra',
|
|
25
|
+
];
|
|
26
|
+
/** The bottom of the lattice — no classification, no compartments */
|
|
27
|
+
export const BOTTOM = Object.freeze({
|
|
28
|
+
level: 0,
|
|
29
|
+
compartments: Object.freeze(new Set()),
|
|
30
|
+
});
|
|
31
|
+
/** Create a label */
|
|
32
|
+
export function makeLabel(level, compartments = []) {
|
|
33
|
+
return {
|
|
34
|
+
level,
|
|
35
|
+
compartments: new Set(compartments),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/** Least Upper Bound — max level, union of compartments */
|
|
39
|
+
export function join(a, b) {
|
|
40
|
+
const level = Math.max(a.level, b.level);
|
|
41
|
+
const compartments = new Set([...a.compartments, ...b.compartments]);
|
|
42
|
+
return { level, compartments };
|
|
43
|
+
}
|
|
44
|
+
/** Does `a` dominate `b`? (a.level >= b.level AND a.compartments ⊇ b.compartments) */
|
|
45
|
+
export function dominates(a, b) {
|
|
46
|
+
if (a.level < b.level)
|
|
47
|
+
return false;
|
|
48
|
+
for (const c of b.compartments) {
|
|
49
|
+
if (!a.compartments.has(c))
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
/** Is label at the bottom of the lattice? */
|
|
55
|
+
export function isBottom(label) {
|
|
56
|
+
return label.level === 0 && label.compartments.size === 0;
|
|
57
|
+
}
|
|
58
|
+
/** Are two labels comparable? (one dominates the other) */
|
|
59
|
+
export function isComparable(a, b) {
|
|
60
|
+
return dominates(a, b) || dominates(b, a);
|
|
61
|
+
}
|
|
62
|
+
/** Are two labels equal? */
|
|
63
|
+
export function labelsEqual(a, b) {
|
|
64
|
+
if (a.level !== b.level)
|
|
65
|
+
return false;
|
|
66
|
+
if (a.compartments.size !== b.compartments.size)
|
|
67
|
+
return false;
|
|
68
|
+
for (const c of a.compartments) {
|
|
69
|
+
if (!b.compartments.has(c))
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
/** Format label for display */
|
|
75
|
+
export function formatLabel(label) {
|
|
76
|
+
const level = LEVEL_NAMES[label.level];
|
|
77
|
+
const comps = [...label.compartments].sort().join(', ');
|
|
78
|
+
return comps ? `${level} {${comps}}` : level;
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=label.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"label.js","sourceRoot":"","sources":["../../../src/lib/ifc/label.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,MAAM,CAAC,MAAM,WAAW,GAAkC;IACxD,CAAC,EAAE,QAAQ;IACX,CAAC,EAAE,UAAU;IACb,CAAC,EAAE,cAAc;IACjB,CAAC,EAAE,qBAAqB;CACzB,CAAC;AAIF,MAAM,CAAC,MAAM,gBAAgB,GAA2B;IACtD,SAAS;IACT,aAAa;IACb,KAAK;IACL,gBAAgB;CACR,CAAC;AAOX,qEAAqE;AACrE,MAAM,CAAC,MAAM,MAAM,GAAkB,MAAM,CAAC,MAAM,CAAC;IACjD,KAAK,EAAE,CAAC;IACR,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,GAAG,EAAe,CAAC;CACpD,CAAkB,CAAC;AAEpB,qBAAqB;AACrB,MAAM,UAAU,SAAS,CAAC,KAAoB,EAAE,eAA8B,EAAE;IAC9E,OAAO;QACL,KAAK;QACL,YAAY,EAAE,IAAI,GAAG,CAAC,YAAY,CAAC;KACpC,CAAC;AACJ,CAAC;AAED,2DAA2D;AAC3D,MAAM,UAAU,IAAI,CAAC,CAAgB,EAAE,CAAgB;IACrD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAkB,CAAC;IAC1D,MAAM,YAAY,GAAG,IAAI,GAAG,CAAc,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;IAClF,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC;AACjC,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,SAAS,CAAC,CAAgB,EAAE,CAAgB;IAC1D,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IACpC,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,CAAC;QAC/B,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;IAC3C,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,6CAA6C;AAC7C,MAAM,UAAU,QAAQ,CAAC,KAAoB;IAC3C,OAAO,KAAK,CAAC,KAAK,KAAK,CAAC,IAAI,KAAK,CAAC,YAAY,CAAC,IAAI,KAAK,CAAC,CAAC;AAC5D,CAAC;AAED,2DAA2D;AAC3D,MAAM,UAAU,YAAY,CAAC,CAAgB,EAAE,CAAgB;IAC7D,OAAO,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC5C,CAAC;AAED,4BAA4B;AAC5B,MAAM,UAAU,WAAW,CAAC,CAAgB,EAAE,CAAgB;IAC5D,IAAI,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IACtC,IAAI,CAAC,CAAC,YAAY,CAAC,IAAI,KAAK,CAAC,CAAC,YAAY,CAAC,IAAI;QAAE,OAAO,KAAK,CAAC;IAC9D,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,CAAC;QAC/B,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;IAC3C,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,+BAA+B;AAC/B,MAAM,UAAU,WAAW,CAAC,KAAoB;IAC9C,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACvC,MAAM,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,YAAY,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxD,OAAO,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,KAAK,KAAK,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;AAC/C,CAAC"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session IFC State — Bell-LaPadula enforcement per session
|
|
3
|
+
*
|
|
4
|
+
* Tracks the security high-water mark for each session:
|
|
5
|
+
* - Labels only go UP (weak tranquility / monotonic)
|
|
6
|
+
* - Taints accumulate and never clear
|
|
7
|
+
* - Outbound operations are checked against *-property (no write down)
|
|
8
|
+
* - Users can grant one-shot trusted-subject escalations
|
|
9
|
+
*
|
|
10
|
+
* State is in-memory, discarded on session end. New session = clean slate.
|
|
11
|
+
*/
|
|
12
|
+
import { type SecurityLabel, type SecurityLevel, type Compartment } from './label.js';
|
|
13
|
+
export type SecurityTaint = 'secrets_detected' | 'credentials_detected' | 'pii_detected' | 'prompt_injection' | 'high_entropy_output';
|
|
14
|
+
export interface LabelHistoryEntry {
|
|
15
|
+
timestamp: number;
|
|
16
|
+
previousLevel: SecurityLevel;
|
|
17
|
+
newLevel: SecurityLevel;
|
|
18
|
+
previousCompartments: Compartment[];
|
|
19
|
+
newCompartments: Compartment[];
|
|
20
|
+
trigger: string;
|
|
21
|
+
}
|
|
22
|
+
export interface SessionIFCState {
|
|
23
|
+
label: SecurityLabel;
|
|
24
|
+
taints: Set<SecurityTaint>;
|
|
25
|
+
outboundStepCount: number;
|
|
26
|
+
labelHistory: LabelHistoryEntry[];
|
|
27
|
+
trustedActions: Set<string>;
|
|
28
|
+
/** Permission mode registered at session start (trusted source of truth for bypass detection) */
|
|
29
|
+
permissionMode?: string;
|
|
30
|
+
}
|
|
31
|
+
export type OutboundChannel = 'file_write' | 'bash_network' | 'web_fetch' | 'git_commit' | 'memory_save';
|
|
32
|
+
export interface WriteDownCheckResult {
|
|
33
|
+
allowed: boolean;
|
|
34
|
+
action: 'allow' | 'deny' | 'ask' | 'warn';
|
|
35
|
+
reason?: string;
|
|
36
|
+
}
|
|
37
|
+
export interface IFCStepLimits {
|
|
38
|
+
highly_confidential: number;
|
|
39
|
+
confidential: number;
|
|
40
|
+
}
|
|
41
|
+
export declare function createSessionIFC(): SessionIFCState;
|
|
42
|
+
/**
|
|
43
|
+
* Raise the session label (monotonic — can only go up).
|
|
44
|
+
* Returns true if the label actually changed.
|
|
45
|
+
*/
|
|
46
|
+
export declare function raiseLabel(state: SessionIFCState, fileLabel: SecurityLabel, trigger: string): boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Add a taint to the session (accumulative, never removed).
|
|
49
|
+
*/
|
|
50
|
+
export declare function addTaint(state: SessionIFCState, taint: SecurityTaint, source: string): void;
|
|
51
|
+
/**
|
|
52
|
+
* Grant a one-shot trusted-subject escalation.
|
|
53
|
+
* The action ID should be unique per operation (e.g., "bash:curl:step42").
|
|
54
|
+
*/
|
|
55
|
+
export declare function grantTrustedAction(state: SessionIFCState, actionId: string): void;
|
|
56
|
+
/**
|
|
57
|
+
* Consume a trusted action (one-shot — removed after use).
|
|
58
|
+
* Returns true if the action was granted and is now consumed.
|
|
59
|
+
*/
|
|
60
|
+
export declare function consumeTrustedAction(state: SessionIFCState, actionId: string): boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Check if an outbound operation is allowed under BLP *-property.
|
|
63
|
+
*
|
|
64
|
+
* Graduated enforcement:
|
|
65
|
+
* - highly_confidential (3): deny all outbound unconditionally
|
|
66
|
+
* - confidential (2): deny if tainted, ask otherwise
|
|
67
|
+
* - internal (1): warn only
|
|
68
|
+
* - public (0): no restriction
|
|
69
|
+
*
|
|
70
|
+
* For file_write, caller must provide the destination file's label.
|
|
71
|
+
*/
|
|
72
|
+
export declare function checkWriteDown(state: SessionIFCState, channel: OutboundChannel, options?: {
|
|
73
|
+
destinationLabel?: SecurityLabel;
|
|
74
|
+
actionId?: string;
|
|
75
|
+
stepLimits?: Partial<IFCStepLimits>;
|
|
76
|
+
}): WriteDownCheckResult;
|
|
77
|
+
/**
|
|
78
|
+
* Increment outbound step counter. Call after every outbound operation.
|
|
79
|
+
*/
|
|
80
|
+
export declare function recordOutboundStep(state: SessionIFCState): void;
|
|
81
|
+
export interface SessionIFCSummary {
|
|
82
|
+
level: SecurityLevel;
|
|
83
|
+
levelName: string;
|
|
84
|
+
compartments: Compartment[];
|
|
85
|
+
taints: SecurityTaint[];
|
|
86
|
+
outboundStepCount: number;
|
|
87
|
+
historyLength: number;
|
|
88
|
+
trustedActionsCount: number;
|
|
89
|
+
formattedLabel: string;
|
|
90
|
+
}
|
|
91
|
+
export declare function summarizeIFC(state: SessionIFCState): SessionIFCSummary;
|
|
92
|
+
//# sourceMappingURL=session-ifc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-ifc.d.ts","sourceRoot":"","sources":["../../../src/lib/ifc/session-ifc.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,WAAW,EAOjB,MAAM,YAAY,CAAC;AAIpB,MAAM,MAAM,aAAa,GACrB,kBAAkB,GAClB,sBAAsB,GACtB,cAAc,GACd,kBAAkB,GAClB,qBAAqB,CAAC;AAE1B,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,aAAa,CAAC;IAC7B,QAAQ,EAAE,aAAa,CAAC;IACxB,oBAAoB,EAAE,WAAW,EAAE,CAAC;IACpC,eAAe,EAAE,WAAW,EAAE,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,aAAa,CAAC;IACrB,MAAM,EAAE,GAAG,CAAC,aAAa,CAAC,CAAC;IAC3B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,iBAAiB,EAAE,CAAC;IAClC,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC5B,iGAAiG;IACjG,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,MAAM,eAAe,GACvB,YAAY,GACZ,cAAc,GACd,WAAW,GACX,YAAY,GACZ,aAAa,CAAC;AAElB,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;CACtB;AAsBD,wBAAgB,gBAAgB,IAAI,eAAe,CAQlD;AAED;;;GAGG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,eAAe,EACtB,SAAS,EAAE,aAAa,EACxB,OAAO,EAAE,MAAM,GACd,OAAO,CA8BT;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAsB3F;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAEjF;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEtF;AAID;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,eAAe,EACtB,OAAO,EAAE,eAAe,EACxB,OAAO,GAAE;IACP,gBAAgB,CAAC,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;CAChC,GACL,oBAAoB,CAkGtB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAE/D;AAID,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,aAAa,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,eAAe,GAAG,iBAAiB,CAWtE"}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session IFC State — Bell-LaPadula enforcement per session
|
|
3
|
+
*
|
|
4
|
+
* Tracks the security high-water mark for each session:
|
|
5
|
+
* - Labels only go UP (weak tranquility / monotonic)
|
|
6
|
+
* - Taints accumulate and never clear
|
|
7
|
+
* - Outbound operations are checked against *-property (no write down)
|
|
8
|
+
* - Users can grant one-shot trusted-subject escalations
|
|
9
|
+
*
|
|
10
|
+
* State is in-memory, discarded on session end. New session = clean slate.
|
|
11
|
+
*/
|
|
12
|
+
import { makeLabel, join, dominates, isBottom, formatLabel, BOTTOM, } from './label.js';
|
|
13
|
+
const DEFAULT_STEP_LIMITS = {
|
|
14
|
+
highly_confidential: 25,
|
|
15
|
+
confidential: 100,
|
|
16
|
+
};
|
|
17
|
+
/** Max label history entries to keep (prevents unbounded growth in long sessions) */
|
|
18
|
+
const MAX_LABEL_HISTORY = 200;
|
|
19
|
+
// ─── Destination labels for outbound channels ───────────────────────
|
|
20
|
+
const CHANNEL_LABELS = {
|
|
21
|
+
file_write: BOTTOM, // Overridden by actual file label at check time
|
|
22
|
+
bash_network: BOTTOM, // Network = public
|
|
23
|
+
web_fetch: BOTTOM, // Network = public
|
|
24
|
+
git_commit: BOTTOM, // Commit message = public
|
|
25
|
+
memory_save: makeLabel(1), // Internal
|
|
26
|
+
};
|
|
27
|
+
// ─── State management ───────────────────────────────────────────────
|
|
28
|
+
export function createSessionIFC() {
|
|
29
|
+
return {
|
|
30
|
+
label: BOTTOM,
|
|
31
|
+
taints: new Set(),
|
|
32
|
+
outboundStepCount: 0,
|
|
33
|
+
labelHistory: [],
|
|
34
|
+
trustedActions: new Set(),
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Raise the session label (monotonic — can only go up).
|
|
39
|
+
* Returns true if the label actually changed.
|
|
40
|
+
*/
|
|
41
|
+
export function raiseLabel(state, fileLabel, trigger) {
|
|
42
|
+
const newLabel = join(state.label, fileLabel);
|
|
43
|
+
// Check if anything changed
|
|
44
|
+
if (newLabel.level === state.label.level) {
|
|
45
|
+
// Check compartments
|
|
46
|
+
let changed = false;
|
|
47
|
+
for (const c of newLabel.compartments) {
|
|
48
|
+
if (!state.label.compartments.has(c)) {
|
|
49
|
+
changed = true;
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (!changed)
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
// Record history (capped to prevent unbounded growth)
|
|
57
|
+
if (state.labelHistory.length < MAX_LABEL_HISTORY) {
|
|
58
|
+
state.labelHistory.push({
|
|
59
|
+
timestamp: Date.now(),
|
|
60
|
+
previousLevel: state.label.level,
|
|
61
|
+
newLevel: newLabel.level,
|
|
62
|
+
previousCompartments: [...state.label.compartments],
|
|
63
|
+
newCompartments: [...newLabel.compartments],
|
|
64
|
+
trigger,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
state.label = newLabel;
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Add a taint to the session (accumulative, never removed).
|
|
72
|
+
*/
|
|
73
|
+
export function addTaint(state, taint, source) {
|
|
74
|
+
if (state.taints.has(taint))
|
|
75
|
+
return;
|
|
76
|
+
state.taints.add(taint);
|
|
77
|
+
// Auto-raise label based on taint
|
|
78
|
+
switch (taint) {
|
|
79
|
+
case 'secrets_detected':
|
|
80
|
+
raiseLabel(state, makeLabel(3, ['secrets']), `taint:${taint} from ${source}`);
|
|
81
|
+
break;
|
|
82
|
+
case 'credentials_detected':
|
|
83
|
+
raiseLabel(state, makeLabel(3, ['credentials']), `taint:${taint} from ${source}`);
|
|
84
|
+
break;
|
|
85
|
+
case 'pii_detected':
|
|
86
|
+
raiseLabel(state, makeLabel(2, ['pii']), `taint:${taint} from ${source}`);
|
|
87
|
+
break;
|
|
88
|
+
case 'prompt_injection':
|
|
89
|
+
// Injection doesn't change label, but taints the session
|
|
90
|
+
break;
|
|
91
|
+
case 'high_entropy_output':
|
|
92
|
+
raiseLabel(state, makeLabel(2, ['secrets']), `taint:${taint} from ${source}`);
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Grant a one-shot trusted-subject escalation.
|
|
98
|
+
* The action ID should be unique per operation (e.g., "bash:curl:step42").
|
|
99
|
+
*/
|
|
100
|
+
export function grantTrustedAction(state, actionId) {
|
|
101
|
+
state.trustedActions.add(actionId);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Consume a trusted action (one-shot — removed after use).
|
|
105
|
+
* Returns true if the action was granted and is now consumed.
|
|
106
|
+
*/
|
|
107
|
+
export function consumeTrustedAction(state, actionId) {
|
|
108
|
+
return state.trustedActions.delete(actionId);
|
|
109
|
+
}
|
|
110
|
+
// ─── *-Property enforcement (no write down) ─────────────────────────
|
|
111
|
+
/**
|
|
112
|
+
* Check if an outbound operation is allowed under BLP *-property.
|
|
113
|
+
*
|
|
114
|
+
* Graduated enforcement:
|
|
115
|
+
* - highly_confidential (3): deny all outbound unconditionally
|
|
116
|
+
* - confidential (2): deny if tainted, ask otherwise
|
|
117
|
+
* - internal (1): warn only
|
|
118
|
+
* - public (0): no restriction
|
|
119
|
+
*
|
|
120
|
+
* For file_write, caller must provide the destination file's label.
|
|
121
|
+
*/
|
|
122
|
+
export function checkWriteDown(state, channel, options = {}) {
|
|
123
|
+
// If session is at bottom (clean), always allow
|
|
124
|
+
if (isBottom(state.label)) {
|
|
125
|
+
return { allowed: true, action: 'allow' };
|
|
126
|
+
}
|
|
127
|
+
// Check one-shot trusted action (consumed on use — delete, not has)
|
|
128
|
+
if (options.actionId && state.trustedActions.delete(options.actionId)) {
|
|
129
|
+
return {
|
|
130
|
+
allowed: true,
|
|
131
|
+
action: 'allow',
|
|
132
|
+
reason: 'Trusted action granted by user (one-shot, now consumed)',
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
// Determine destination label
|
|
136
|
+
const destLabel = channel === 'file_write' && options.destinationLabel
|
|
137
|
+
? options.destinationLabel
|
|
138
|
+
: CHANNEL_LABELS[channel];
|
|
139
|
+
// For file_write: check if destination dominates session (standard BLP)
|
|
140
|
+
if (channel === 'file_write' && options.destinationLabel) {
|
|
141
|
+
if (dominates(options.destinationLabel, state.label)) {
|
|
142
|
+
// Writing to equal or higher classification — always OK
|
|
143
|
+
return { allowed: true, action: 'allow' };
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
// Graduated enforcement by session level
|
|
147
|
+
const limits = { ...DEFAULT_STEP_LIMITS, ...options.stepLimits };
|
|
148
|
+
if (state.label.level === 3) {
|
|
149
|
+
// Highly confidential: deny all outbound (except file_write to same/higher level)
|
|
150
|
+
if (state.outboundStepCount >= limits.highly_confidential) {
|
|
151
|
+
return {
|
|
152
|
+
allowed: false,
|
|
153
|
+
action: 'deny',
|
|
154
|
+
reason: `Session has read highly confidential data (step limit ${limits.highly_confidential} reached). ` +
|
|
155
|
+
`All outbound operations blocked. Session label: ${formatLabel(state.label)}`,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
return {
|
|
159
|
+
allowed: false,
|
|
160
|
+
action: 'deny',
|
|
161
|
+
reason: `Session has read highly confidential data. ` +
|
|
162
|
+
`${channel} to ${formatLabel(destLabel)} blocked (no write down). ` +
|
|
163
|
+
`Session label: ${formatLabel(state.label)}`,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
if (state.label.level === 2) {
|
|
167
|
+
// Confidential: deny if tainted, ask otherwise
|
|
168
|
+
if (state.taints.size > 0) {
|
|
169
|
+
return {
|
|
170
|
+
allowed: false,
|
|
171
|
+
action: 'deny',
|
|
172
|
+
reason: `Session is confidential + tainted (${[...state.taints].join(', ')}). ` +
|
|
173
|
+
`${channel} blocked. Session label: ${formatLabel(state.label)}`,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
if (state.outboundStepCount >= limits.confidential) {
|
|
177
|
+
return {
|
|
178
|
+
allowed: false,
|
|
179
|
+
action: 'ask',
|
|
180
|
+
reason: `Session has read confidential data (step limit ${limits.confidential} approaching). ` +
|
|
181
|
+
`${channel} requires approval. Session label: ${formatLabel(state.label)}`,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
return {
|
|
185
|
+
allowed: false,
|
|
186
|
+
action: 'ask',
|
|
187
|
+
reason: `Session has read confidential data. ` +
|
|
188
|
+
`${channel} to ${formatLabel(destLabel)} requires approval (no write down). ` +
|
|
189
|
+
`Session label: ${formatLabel(state.label)}`,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
if (state.label.level === 1) {
|
|
193
|
+
// Internal: warn only (don't block)
|
|
194
|
+
return {
|
|
195
|
+
allowed: true,
|
|
196
|
+
action: 'warn',
|
|
197
|
+
reason: `Session has read internal data. ` +
|
|
198
|
+
`${channel} allowed but noted. Session label: ${formatLabel(state.label)}`,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
// Level 0 (public) — no restriction
|
|
202
|
+
return { allowed: true, action: 'allow' };
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Increment outbound step counter. Call after every outbound operation.
|
|
206
|
+
*/
|
|
207
|
+
export function recordOutboundStep(state) {
|
|
208
|
+
state.outboundStepCount++;
|
|
209
|
+
}
|
|
210
|
+
export function summarizeIFC(state) {
|
|
211
|
+
return {
|
|
212
|
+
level: state.label.level,
|
|
213
|
+
levelName: formatLabel(state.label).split(' ')[0],
|
|
214
|
+
compartments: [...state.label.compartments],
|
|
215
|
+
taints: [...state.taints],
|
|
216
|
+
outboundStepCount: state.outboundStepCount,
|
|
217
|
+
historyLength: state.labelHistory.length,
|
|
218
|
+
trustedActionsCount: state.trustedActions.size,
|
|
219
|
+
formattedLabel: formatLabel(state.label),
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
//# sourceMappingURL=session-ifc.js.map
|