yuangs 2.29.0 → 2.30.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/README.md +290 -0
- package/dist/agent/index.d.ts +2 -0
- package/dist/agent/index.js +2 -0
- package/dist/agent/index.js.map +1 -1
- package/dist/agent/policy/engine.d.ts +14 -0
- package/dist/agent/policy/engine.js +76 -0
- package/dist/agent/policy/engine.js.map +1 -0
- package/dist/agent/policy/index.d.ts +3 -0
- package/dist/agent/policy/index.js +20 -0
- package/dist/agent/policy/index.js.map +1 -0
- package/dist/agent/policy/policies/noDangerousShell.d.ts +7 -0
- package/dist/agent/policy/policies/noDangerousShell.js +45 -0
- package/dist/agent/policy/policies/noDangerousShell.js.map +1 -0
- package/dist/agent/policy/types.d.ts +23 -0
- package/dist/agent/policy/types.js +3 -0
- package/dist/agent/policy/types.js.map +1 -0
- package/dist/agent/replay/events.d.ts +21 -0
- package/dist/agent/replay/events.js +3 -0
- package/dist/agent/replay/events.js.map +1 -0
- package/dist/agent/replay/index.d.ts +3 -0
- package/dist/agent/replay/index.js +20 -0
- package/dist/agent/replay/index.js.map +1 -0
- package/dist/agent/replay/recorder.d.ts +11 -0
- package/dist/agent/replay/recorder.js +51 -0
- package/dist/agent/replay/recorder.js.map +1 -0
- package/dist/agent/replay/replayer.d.ts +21 -0
- package/dist/agent/replay/replayer.js +65 -0
- package/dist/agent/replay/replayer.js.map +1 -0
- package/dist/agent/skills.d.ts +5 -0
- package/dist/agent/skills.js +7 -3
- package/dist/agent/skills.js.map +1 -1
- package/dist/api/index.d.ts +1 -0
- package/dist/api/index.js +18 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/registryAPI.d.ts +22 -0
- package/dist/api/registryAPI.js +66 -0
- package/dist/api/registryAPI.js.map +1 -0
- package/dist/audit/index.d.ts +1 -0
- package/dist/audit/index.js +18 -0
- package/dist/audit/index.js.map +1 -0
- package/dist/audit/timeline.d.ts +75 -0
- package/dist/audit/timeline.js +254 -0
- package/dist/audit/timeline.js.map +1 -0
- package/dist/cli.js +10 -1
- package/dist/cli.js.map +1 -1
- package/dist/commands/explainCommands.d.ts +2 -0
- package/dist/commands/explainCommands.js +36 -0
- package/dist/commands/explainCommands.js.map +1 -0
- package/dist/commands/registryCommands.d.ts +2 -0
- package/dist/commands/registryCommands.js +243 -0
- package/dist/commands/registryCommands.js.map +1 -0
- package/dist/commands/replayCommands.d.ts +2 -0
- package/dist/commands/replayCommands.js +75 -0
- package/dist/commands/replayCommands.js.map +1 -0
- package/dist/commands/skillsCommands.d.ts +2 -0
- package/dist/commands/skillsCommands.js +114 -0
- package/dist/commands/skillsCommands.js.map +1 -0
- package/dist/core/executionRecord.d.ts +8 -0
- package/dist/core/executionRecord.js +2 -0
- package/dist/core/executionRecord.js.map +1 -1
- package/dist/core/explain.d.ts +8 -0
- package/dist/core/explain.js +84 -0
- package/dist/core/explain.js.map +1 -0
- package/dist/core/replayDiff.d.ts +55 -0
- package/dist/core/replayDiff.js +205 -0
- package/dist/core/replayDiff.js.map +1 -0
- package/dist/core/replayEngine.d.ts +3 -0
- package/dist/core/replayEngine.js +23 -1
- package/dist/core/replayEngine.js.map +1 -1
- package/dist/registry/errors.d.ts +21 -0
- package/dist/registry/errors.js +35 -0
- package/dist/registry/errors.js.map +1 -0
- package/dist/registry/index.d.ts +3 -0
- package/dist/registry/index.js +20 -0
- package/dist/registry/index.js.map +1 -0
- package/dist/registry/manifest.d.ts +43 -0
- package/dist/registry/manifest.js +32 -0
- package/dist/registry/manifest.js.map +1 -0
- package/dist/registry/registry.d.ts +20 -0
- package/dist/registry/registry.js +201 -0
- package/dist/registry/registry.js.map +1 -0
- package/dist/risk/explainer.d.ts +39 -0
- package/dist/risk/explainer.js +214 -0
- package/dist/risk/explainer.js.map +1 -0
- package/dist/risk/index.d.ts +1 -0
- package/dist/risk/index.js +18 -0
- package/dist/risk/index.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -634,6 +634,296 @@ Then `yuangs` is for you.
|
|
|
634
634
|
|
|
635
635
|
## Status
|
|
636
636
|
|
|
637
|
+
`yuangs` is actively evolving.
|
|
638
|
+
The core governance model is stable; interfaces are still sharpening.
|
|
639
|
+
|
|
640
|
+
Contributions, ideas, and principled criticism are welcome.
|
|
641
|
+
|
|
642
|
+
> **"AI should never appear smarter than input unless explicitly asked."**
|
|
643
|
+
|
|
644
|
+
---
|
|
645
|
+
|
|
646
|
+
# Phase 2: Explainability & Governance (v1)
|
|
647
|
+
|
|
648
|
+
## 🎯 Overview
|
|
649
|
+
|
|
650
|
+
Phase 2 introduces **system observability and control** without changing core behavior:
|
|
651
|
+
- ✅ Explainability: Human-readable execution explanations
|
|
652
|
+
- ✅ Replay++: Dry-run, explain, and diff capabilities
|
|
653
|
+
- ✅ Skill Control: Enable/disable skills for fine-grained control
|
|
654
|
+
|
|
655
|
+
---
|
|
656
|
+
|
|
657
|
+
## 📦 New Commands
|
|
658
|
+
|
|
659
|
+
### `yuangs explain [id | last]`
|
|
660
|
+
|
|
661
|
+
**Purpose**: Explain why the system made a decision
|
|
662
|
+
|
|
663
|
+
**Usage**:
|
|
664
|
+
```bash
|
|
665
|
+
# Explain the most recent execution
|
|
666
|
+
yuangs explain last
|
|
667
|
+
|
|
668
|
+
# Explain a specific execution by ID
|
|
669
|
+
yuangs explain exec_1768820380225_rgts34981
|
|
670
|
+
```
|
|
671
|
+
|
|
672
|
+
**Output Format (v1)**:
|
|
673
|
+
```
|
|
674
|
+
=== Execution Explanation ===
|
|
675
|
+
[1] Command
|
|
676
|
+
- Name: ai-command
|
|
677
|
+
- Args: echo "hello"
|
|
678
|
+
|
|
679
|
+
[2] Decision
|
|
680
|
+
- Strategy: capability-match
|
|
681
|
+
- Selected Model: gemini-2.5-flash-lite
|
|
682
|
+
- Reason: Capability-based selection with fallback support
|
|
683
|
+
|
|
684
|
+
[3] Model
|
|
685
|
+
- Name: gemini-2.5-flash-lite
|
|
686
|
+
- Provider: aiproxy
|
|
687
|
+
- Context Window: 8000
|
|
688
|
+
- Cost Profile: low
|
|
689
|
+
|
|
690
|
+
[4] Skills
|
|
691
|
+
- (none)
|
|
692
|
+
|
|
693
|
+
[5] Meta
|
|
694
|
+
- Execution ID: exec_1768820380225_rgts34981
|
|
695
|
+
- Timestamp: 2026-01-19T10:59:40.225Z
|
|
696
|
+
- Replayable: true
|
|
697
|
+
- Version: unknown
|
|
698
|
+
=============================
|
|
699
|
+
```
|
|
700
|
+
|
|
701
|
+
**Key Features**:
|
|
702
|
+
- ✅ Pure read-only operation (no side effects)
|
|
703
|
+
- ✅ Stable, snapshot-able output
|
|
704
|
+
- ✅ Future-proof for diff/audit workflows
|
|
705
|
+
|
|
706
|
+
---
|
|
707
|
+
|
|
708
|
+
### `yuangs replay <id> [options]`
|
|
709
|
+
|
|
710
|
+
**Purpose**: Replay an execution with control flags
|
|
711
|
+
|
|
712
|
+
**Options**:
|
|
713
|
+
| Option | Description |
|
|
714
|
+
|--------|-------------|
|
|
715
|
+
| `-s, --strict` | Strict replay (use exact model) |
|
|
716
|
+
| `-c, --compatible` | Compatible replay (allow fallback) |
|
|
717
|
+
| `-r, --re-evaluate` | Re-evaluate with current config |
|
|
718
|
+
| `-v, --verbose` | Verbose output |
|
|
719
|
+
| `--dry` | Dry run - show what would happen without executing |
|
|
720
|
+
| `--explain` | Show explanation before replay |
|
|
721
|
+
| `--diff` | Show diff between original and current config |
|
|
722
|
+
|
|
723
|
+
**Usage Examples**:
|
|
724
|
+
```bash
|
|
725
|
+
# Dry run with explanation
|
|
726
|
+
yuangs replay exec_1768820380225_rgts34981 --dry --explain
|
|
727
|
+
|
|
728
|
+
# Show diff only (no execution)
|
|
729
|
+
yuangs replay exec_1768820380225_rgts34981 --diff --dry
|
|
730
|
+
|
|
731
|
+
# Full replay with diff
|
|
732
|
+
yuangs replay exec_1768820380225_rgts34981 --diff
|
|
733
|
+
```
|
|
734
|
+
|
|
735
|
+
**Replay Behavior Matrix**:
|
|
736
|
+
| explain | dry | strict | Behavior |
|
|
737
|
+
|--------|-----|--------|----------|
|
|
738
|
+
| ✅ | ✅ | any | Explain only, no execution |
|
|
739
|
+
| ✅ | ❌ | ✅ | Explain → Replay |
|
|
740
|
+
| ❌ | ✅ | ✅ | Print strict info → Exit |
|
|
741
|
+
| ❌ | ❌ | ✅ | Normal replay |
|
|
742
|
+
|
|
743
|
+
**Diff Output**:
|
|
744
|
+
```
|
|
745
|
+
=== Replay Diff ===
|
|
746
|
+
[Decision]
|
|
747
|
+
- no change
|
|
748
|
+
|
|
749
|
+
[Model]
|
|
750
|
+
- no change
|
|
751
|
+
|
|
752
|
+
[Skills]
|
|
753
|
+
- no change
|
|
754
|
+
===================
|
|
755
|
+
```
|
|
756
|
+
|
|
757
|
+
---
|
|
758
|
+
|
|
759
|
+
### `yuangs skills <subcommand>`
|
|
760
|
+
|
|
761
|
+
**Purpose**: Manage skill library
|
|
762
|
+
|
|
763
|
+
**Subcommands**:
|
|
764
|
+
```bash
|
|
765
|
+
# List all skills with scores
|
|
766
|
+
yuangs skills list
|
|
767
|
+
|
|
768
|
+
# Explain a specific skill
|
|
769
|
+
yuangs skills explain <skill-name>
|
|
770
|
+
|
|
771
|
+
# Disable a skill
|
|
772
|
+
yuangs skills disable <skill-name>
|
|
773
|
+
|
|
774
|
+
# Enable a skill
|
|
775
|
+
yuangs skills enable <skill-name>
|
|
776
|
+
```
|
|
777
|
+
|
|
778
|
+
**Output Example** (`skills list`):
|
|
779
|
+
```
|
|
780
|
+
📦 Skills (3)
|
|
781
|
+
|
|
782
|
+
✔ deploy-production
|
|
783
|
+
Confidence: 72%
|
|
784
|
+
Success: 8 / Failure: 1
|
|
785
|
+
Last used: 2 days ago
|
|
786
|
+
|
|
787
|
+
✔ cleanup-logs
|
|
788
|
+
Confidence: 41%
|
|
789
|
+
Success: 5 / Failure: 7
|
|
790
|
+
Last used: 1 day ago
|
|
791
|
+
|
|
792
|
+
⊘ legacy-search (disabled)
|
|
793
|
+
Confidence: 23%
|
|
794
|
+
Success: 2 / Failure: 6
|
|
795
|
+
Last used: 7 days ago
|
|
796
|
+
```
|
|
797
|
+
|
|
798
|
+
**Key Features**:
|
|
799
|
+
- ✅ Skills can be disabled without deletion
|
|
800
|
+
- ✅ Skills are scored and sorted by relevance
|
|
801
|
+
- ✅ Disabled skills don't affect new decisions
|
|
802
|
+
- ✅ All skills remain visible in `explain` output
|
|
803
|
+
|
|
804
|
+
---
|
|
805
|
+
|
|
806
|
+
## 🧭 Explain Output Spec v1
|
|
807
|
+
|
|
808
|
+
The explain output follows a strict format designed for:
|
|
809
|
+
- ✅ Human readability
|
|
810
|
+
- ✅ Stability and snapshot compatibility
|
|
811
|
+
- ✅ Future diff/audit workflows
|
|
812
|
+
- ✅ No implementation coupling
|
|
813
|
+
|
|
814
|
+
**Structure** (5 sections, immutable order):
|
|
815
|
+
1. `[1] Command` - User input layer
|
|
816
|
+
2. `[2] Decision` - Decision-making core
|
|
817
|
+
3. `[3] Model` - Execution environment
|
|
818
|
+
4. `[4] Skills` - Skills that influenced decision
|
|
819
|
+
5. `[5] Meta` - Audit/replay metadata
|
|
820
|
+
|
|
821
|
+
**Important Notes**:
|
|
822
|
+
- ⚠️ Do NOT change format without bumping spec version
|
|
823
|
+
- ✅ Output is pure text (no color for snapshots)
|
|
824
|
+
- ✅ Same execution record = 100% reproducible output
|
|
825
|
+
|
|
826
|
+
---
|
|
827
|
+
|
|
828
|
+
## 🔒 Skills & Enabled State
|
|
829
|
+
|
|
830
|
+
Skills now have an `enabled` field that controls their participation in new decisions:
|
|
831
|
+
|
|
832
|
+
**Default Behavior**:
|
|
833
|
+
- ✅ New skills: `enabled: true`
|
|
834
|
+
- ✅ Legacy skills: `enabled: true` (if field missing)
|
|
835
|
+
- ❌ Disabled skills: Not included in `getRelevantSkills()`
|
|
836
|
+
|
|
837
|
+
**Use Cases**:
|
|
838
|
+
1. **Governance**: Temporarily disable risky skills
|
|
839
|
+
2. **A/B Testing**: Compare different skill configurations
|
|
840
|
+
3. **Rollback**: Disable a newly-added skill without deletion
|
|
841
|
+
4. **Audit**: View disabled skills in explain output
|
|
842
|
+
|
|
843
|
+
**CLI Commands**:
|
|
844
|
+
```bash
|
|
845
|
+
# Disable a skill
|
|
846
|
+
yuangs skills disable risky-operation
|
|
847
|
+
|
|
848
|
+
# List to verify
|
|
849
|
+
yuangs skills list
|
|
850
|
+
|
|
851
|
+
# Re-enable if needed
|
|
852
|
+
yuangs skills enable risky-operation
|
|
853
|
+
```
|
|
854
|
+
|
|
855
|
+
---
|
|
856
|
+
|
|
857
|
+
## 🧪 Testing & Snapshots
|
|
858
|
+
|
|
859
|
+
### Creating Explain Snapshots
|
|
860
|
+
|
|
861
|
+
```bash
|
|
862
|
+
# Create a snapshot of the last execution
|
|
863
|
+
yuangs replay exec_1768820380225_rgts34981 --explain --dry > snapshot.txt
|
|
864
|
+
```
|
|
865
|
+
|
|
866
|
+
Snapshots are useful for:
|
|
867
|
+
- ✅ Regression testing
|
|
868
|
+
- ✅ Output format verification
|
|
869
|
+
- ✅ Documentation examples
|
|
870
|
+
- ✅ Audit trails
|
|
871
|
+
|
|
872
|
+
---
|
|
873
|
+
|
|
874
|
+
## 📝 Implementation Notes
|
|
875
|
+
|
|
876
|
+
### Explain Output v1
|
|
877
|
+
|
|
878
|
+
**File**: `src/core/explain.ts`
|
|
879
|
+
|
|
880
|
+
**Key Design**:
|
|
881
|
+
- Pure function (no side effects)
|
|
882
|
+
- No external dependencies on global state
|
|
883
|
+
- Uses existing `ExecutionRecord` structure
|
|
884
|
+
- Stable formatting (versioned)
|
|
885
|
+
|
|
886
|
+
---
|
|
887
|
+
|
|
888
|
+
### Replay Diff
|
|
889
|
+
|
|
890
|
+
**File**: `src/core/replayDiff.ts`
|
|
891
|
+
|
|
892
|
+
**Key Design**:
|
|
893
|
+
- Compares Decision, Model, and Skills layers
|
|
894
|
+
- Shows added/removed/changed skills
|
|
895
|
+
- Semantic diff (not token-level)
|
|
896
|
+
- Compatible with Explain v1 format
|
|
897
|
+
|
|
898
|
+
---
|
|
899
|
+
|
|
900
|
+
### Skills Control
|
|
901
|
+
|
|
902
|
+
**File**: `src/agent/skills.ts`
|
|
903
|
+
|
|
904
|
+
**Key Changes**:
|
|
905
|
+
- Added `enabled: boolean` field to `Skill` interface
|
|
906
|
+
- Exported `computeSkillScore()` for CLI usage
|
|
907
|
+
- `getRelevantSkills()` filters disabled skills
|
|
908
|
+
|
|
909
|
+
---
|
|
910
|
+
|
|
911
|
+
## ✅ Phase 2 Completion
|
|
912
|
+
|
|
913
|
+
All Phase 2 objectives are complete:
|
|
914
|
+
|
|
915
|
+
- [x] Explainability (ExecutionRecord-level)
|
|
916
|
+
- [x] Replay dry / explain / strict
|
|
917
|
+
- [x] Skill scoring & enable flag
|
|
918
|
+
- [x] CLI wiring for all three
|
|
919
|
+
- [x] Replay diff implementation
|
|
920
|
+
- [x] Skills enabled filtering
|
|
921
|
+
- [x] Explain v1 specification
|
|
922
|
+
- [x] Snapshot testing capability
|
|
923
|
+
|
|
924
|
+
**Next Phase**: Phase 3 - Advanced governance & project-level intelligence
|
|
925
|
+
|
|
926
|
+
|
|
637
927
|
`yuangs` is actively evolving.
|
|
638
928
|
The core governance model is stable; interfaces are still sharpening.
|
|
639
929
|
|
package/dist/agent/index.d.ts
CHANGED
package/dist/agent/index.js
CHANGED
|
@@ -31,4 +31,6 @@ var executor_1 = require("./executor");
|
|
|
31
31
|
Object.defineProperty(exports, "ToolExecutor", { enumerable: true, get: function () { return executor_1.ToolExecutor; } });
|
|
32
32
|
var contextManager_1 = require("./contextManager");
|
|
33
33
|
Object.defineProperty(exports, "ContextManager", { enumerable: true, get: function () { return contextManager_1.ContextManager; } });
|
|
34
|
+
__exportStar(require("./policy"), exports);
|
|
35
|
+
__exportStar(require("./replay"), exports);
|
|
34
36
|
//# sourceMappingURL=index.js.map
|
package/dist/agent/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/agent/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,iDAAgD;AAAvC,8GAAA,aAAa,OAAA;AACtB,0CAAwB;AACxB,0CAAwB;AACxB,6BAAsC;AAA7B,oGAAA,aAAa,OAAA;AACtB,+BAA2C;AAAlC,yGAAA,iBAAiB,OAAA;AAC1B,2CAA0C;AAAjC,wGAAA,UAAU,OAAA;AACnB,2CAAiD;AAAxC,+GAAA,iBAAiB,OAAA;AAC1B,uCAA0C;AAAjC,wGAAA,YAAY,OAAA;AACrB,mDAAkD;AAAzC,gHAAA,cAAc,OAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/agent/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,iDAAgD;AAAvC,8GAAA,aAAa,OAAA;AACtB,0CAAwB;AACxB,0CAAwB;AACxB,6BAAsC;AAA7B,oGAAA,aAAa,OAAA;AACtB,+BAA2C;AAAlC,yGAAA,iBAAiB,OAAA;AAC1B,2CAA0C;AAAjC,wGAAA,UAAU,OAAA;AACnB,2CAAiD;AAAxC,+GAAA,iBAAiB,OAAA;AAC1B,uCAA0C;AAAjC,wGAAA,YAAY,OAAA;AACrB,mDAAkD;AAAzC,gHAAA,cAAc,OAAA;AACvB,2CAAyB;AACzB,2CAAyB"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Policy, PolicyContext, PolicyResult } from './types';
|
|
2
|
+
import { RiskLevel } from '../state';
|
|
3
|
+
export declare class PolicyEngine {
|
|
4
|
+
private policies;
|
|
5
|
+
registerPolicy(policy: Policy): void;
|
|
6
|
+
unregisterPolicy(name: string): void;
|
|
7
|
+
evaluate(context: PolicyContext): Promise<PolicyResult>;
|
|
8
|
+
evaluateRisk(action: {
|
|
9
|
+
type: string;
|
|
10
|
+
payload: any;
|
|
11
|
+
}): RiskLevel;
|
|
12
|
+
private containsDangerousCommand;
|
|
13
|
+
}
|
|
14
|
+
export declare const policyEngine: PolicyEngine;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.policyEngine = exports.PolicyEngine = void 0;
|
|
4
|
+
class PolicyEngine {
|
|
5
|
+
policies = new Map();
|
|
6
|
+
registerPolicy(policy) {
|
|
7
|
+
this.policies.set(policy.name, policy);
|
|
8
|
+
}
|
|
9
|
+
unregisterPolicy(name) {
|
|
10
|
+
this.policies.delete(name);
|
|
11
|
+
}
|
|
12
|
+
async evaluate(context) {
|
|
13
|
+
let finalResult = {
|
|
14
|
+
allowed: true,
|
|
15
|
+
reason: 'All policies passed'
|
|
16
|
+
};
|
|
17
|
+
for (const [name, policy] of this.policies) {
|
|
18
|
+
const result = await policy.evaluate(context);
|
|
19
|
+
if (!result.allowed) {
|
|
20
|
+
return {
|
|
21
|
+
allowed: false,
|
|
22
|
+
reason: `Policy "${name}" blocked: ${result.reason}`,
|
|
23
|
+
requiresEscalation: result.requiresEscalation || false,
|
|
24
|
+
suggestedActions: result.suggestedActions
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
if (result.requiresEscalation) {
|
|
28
|
+
finalResult.requiresEscalation = true;
|
|
29
|
+
finalResult.suggestedActions = result.suggestedActions;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return finalResult;
|
|
33
|
+
}
|
|
34
|
+
evaluateRisk(action) {
|
|
35
|
+
const { type, payload } = action;
|
|
36
|
+
if (type === 'tool_call') {
|
|
37
|
+
const toolName = payload.tool_name;
|
|
38
|
+
const lowRiskTools = ['read_file', 'list_files', 'web_search'];
|
|
39
|
+
if (lowRiskTools.includes(toolName)) {
|
|
40
|
+
return 'low';
|
|
41
|
+
}
|
|
42
|
+
const mediumRiskTools = ['write_file', 'shell'];
|
|
43
|
+
if (mediumRiskTools.includes(toolName)) {
|
|
44
|
+
const cmd = payload.parameters?.command || payload.command || '';
|
|
45
|
+
if (this.containsDangerousCommand(cmd)) {
|
|
46
|
+
return 'high';
|
|
47
|
+
}
|
|
48
|
+
return 'medium';
|
|
49
|
+
}
|
|
50
|
+
return 'medium';
|
|
51
|
+
}
|
|
52
|
+
if (type === 'shell_cmd') {
|
|
53
|
+
const cmd = payload.command || '';
|
|
54
|
+
if (this.containsDangerousCommand(cmd)) {
|
|
55
|
+
return 'high';
|
|
56
|
+
}
|
|
57
|
+
return 'medium';
|
|
58
|
+
}
|
|
59
|
+
return 'low';
|
|
60
|
+
}
|
|
61
|
+
containsDangerousCommand(cmd) {
|
|
62
|
+
const dangerousPatterns = [
|
|
63
|
+
/rm\s+-rf\s+\//,
|
|
64
|
+
/rm\s+-rf\s+~/,
|
|
65
|
+
/>\s*\/dev\/null/,
|
|
66
|
+
/dd\s+if=/,
|
|
67
|
+
/mkfs/,
|
|
68
|
+
/format/,
|
|
69
|
+
/sudo\s+rm/
|
|
70
|
+
];
|
|
71
|
+
return dangerousPatterns.some(pattern => pattern.test(cmd));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
exports.PolicyEngine = PolicyEngine;
|
|
75
|
+
exports.policyEngine = new PolicyEngine();
|
|
76
|
+
//# sourceMappingURL=engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../../src/agent/policy/engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./types"), exports);
|
|
18
|
+
__exportStar(require("./engine"), exports);
|
|
19
|
+
__exportStar(require("./policies/noDangerousShell"), exports);
|
|
20
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/agent/policy/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,0CAAwB;AACxB,2CAAyB;AACzB,8DAA4C"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Policy, PolicyContext, PolicyResult } from '../types';
|
|
2
|
+
export declare class NoDangerousShellPolicy implements Policy {
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
evaluate(context: PolicyContext): PolicyResult;
|
|
6
|
+
}
|
|
7
|
+
export declare const noDangerousShellPolicy: NoDangerousShellPolicy;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.noDangerousShellPolicy = exports.NoDangerousShellPolicy = void 0;
|
|
4
|
+
class NoDangerousShellPolicy {
|
|
5
|
+
name = 'no-dangerous-shell';
|
|
6
|
+
description = 'Prevents execution of dangerous shell commands';
|
|
7
|
+
evaluate(context) {
|
|
8
|
+
const { action } = context;
|
|
9
|
+
if (action.type === 'shell_cmd') {
|
|
10
|
+
const command = action.payload?.command || '';
|
|
11
|
+
const dangerousPatterns = [
|
|
12
|
+
{ pattern: /rm\s+-rf\s+\//, name: 'rm -rf /', risk: 'high' },
|
|
13
|
+
{ pattern: /rm\s+-rf\s+~/, name: 'rm -rf ~', risk: 'high' },
|
|
14
|
+
{ pattern: />\s*\/dev\/null/, name: 'Redirect to /dev/null', risk: 'medium' },
|
|
15
|
+
{ pattern: /dd\s+if=/, name: 'dd command', risk: 'high' },
|
|
16
|
+
{ pattern: /mkfs/, name: 'mkfs (filesystem creation)', risk: 'high' },
|
|
17
|
+
{ pattern: /format/, name: 'format command', risk: 'high' },
|
|
18
|
+
{ pattern: /sudo\s+rm/, name: 'sudo rm', risk: 'high' },
|
|
19
|
+
{ pattern: /chmod\s+777\s+\/(?!dev)/, name: 'chmod 777 on system', risk: 'high' },
|
|
20
|
+
{ pattern: /:\s*~\(\)/, name: 'fork bomb', risk: 'high' }
|
|
21
|
+
];
|
|
22
|
+
for (const { pattern, name, risk } of dangerousPatterns) {
|
|
23
|
+
if (pattern.test(command)) {
|
|
24
|
+
return {
|
|
25
|
+
allowed: false,
|
|
26
|
+
reason: `Dangerous command detected: ${name} (${risk} risk)`,
|
|
27
|
+
requiresEscalation: risk === 'high',
|
|
28
|
+
suggestedActions: [
|
|
29
|
+
`Review the command: "${command}"`,
|
|
30
|
+
'Consider using safer alternatives',
|
|
31
|
+
'Break down the operation into smaller, safer steps'
|
|
32
|
+
]
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
allowed: true,
|
|
39
|
+
reason: 'No dangerous patterns detected'
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
exports.NoDangerousShellPolicy = NoDangerousShellPolicy;
|
|
44
|
+
exports.noDangerousShellPolicy = new NoDangerousShellPolicy();
|
|
45
|
+
//# sourceMappingURL=noDangerousShell.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"noDangerousShell.js","sourceRoot":"","sources":["../../../../src/agent/policy/policies/noDangerousShell.ts"],"names":[],"mappings":";;;AAGA,MAAa,sBAAsB;IACjC,IAAI,GAAG,oBAAoB,CAAC;IAC5B,WAAW,GAAG,gDAAgD,CAAC;IAE/D,QAAQ,CAAC,OAAsB;QAC7B,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;QAE3B,IAAI,MAAM,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YAChC,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,EAAE,OAAO,IAAI,EAAE,CAAC;YAE9C,MAAM,iBAAiB,GAAG;gBACxB,EAAE,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE;gBAC5D,EAAE,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE;gBAC3D,EAAE,OAAO,EAAE,iBAAiB,EAAE,IAAI,EAAE,uBAAuB,EAAE,IAAI,EAAE,QAAQ,EAAE;gBAC7E,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE;gBACzD,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,4BAA4B,EAAE,IAAI,EAAE,MAAM,EAAE;gBACrE,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,EAAE;gBAC3D,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE;gBACvD,EAAE,OAAO,EAAE,yBAAyB,EAAE,IAAI,EAAE,qBAAqB,EAAE,IAAI,EAAE,MAAM,EAAE;gBACjF,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE;aAC1D,CAAC;YAEF,KAAK,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,iBAAiB,EAAE,CAAC;gBACxD,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;oBAC1B,OAAO;wBACL,OAAO,EAAE,KAAK;wBACd,MAAM,EAAE,+BAA+B,IAAI,KAAK,IAAI,QAAQ;wBAC5D,kBAAkB,EAAE,IAAI,KAAK,MAAM;wBACnC,gBAAgB,EAAE;4BAChB,wBAAwB,OAAO,GAAG;4BAClC,mCAAmC;4BACnC,oDAAoD;yBACrD;qBACF,CAAC;gBACJ,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO;YACL,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,gCAAgC;SACzC,CAAC;IACJ,CAAC;CACF;AA3CD,wDA2CC;AAEY,QAAA,sBAAsB,GAAG,IAAI,sBAAsB,EAAE,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export interface PolicyContext {
|
|
2
|
+
action: {
|
|
3
|
+
type: string;
|
|
4
|
+
payload: any;
|
|
5
|
+
};
|
|
6
|
+
user?: {
|
|
7
|
+
permissions: string[];
|
|
8
|
+
};
|
|
9
|
+
environment?: {
|
|
10
|
+
isProduction: boolean;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
export interface PolicyResult {
|
|
14
|
+
allowed: boolean;
|
|
15
|
+
reason?: string;
|
|
16
|
+
requiresEscalation?: boolean;
|
|
17
|
+
suggestedActions?: string[];
|
|
18
|
+
}
|
|
19
|
+
export interface Policy {
|
|
20
|
+
name: string;
|
|
21
|
+
description: string;
|
|
22
|
+
evaluate(context: PolicyContext): PolicyResult | Promise<PolicyResult>;
|
|
23
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/agent/policy/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export type EventType = 'state_transition' | 'llm_call' | 'tool_execution' | 'governance_decision' | 'observation_recorded' | 'evaluation_result' | 'error_occurred';
|
|
2
|
+
export interface RuntimeEvent {
|
|
3
|
+
id: string;
|
|
4
|
+
timestamp: number;
|
|
5
|
+
executionId: string;
|
|
6
|
+
type: EventType;
|
|
7
|
+
data: {
|
|
8
|
+
from?: string;
|
|
9
|
+
to?: string;
|
|
10
|
+
action?: any;
|
|
11
|
+
decision?: any;
|
|
12
|
+
result?: any;
|
|
13
|
+
error?: string;
|
|
14
|
+
};
|
|
15
|
+
metadata?: Record<string, any>;
|
|
16
|
+
}
|
|
17
|
+
export interface EventRecorder {
|
|
18
|
+
record(event: RuntimeEvent): void;
|
|
19
|
+
flush(): Promise<void>;
|
|
20
|
+
getEvents(executionId?: string): RuntimeEvent[];
|
|
21
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../../src/agent/replay/events.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./events"), exports);
|
|
18
|
+
__exportStar(require("./recorder"), exports);
|
|
19
|
+
__exportStar(require("./replayer"), exports);
|
|
20
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/agent/replay/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAyB;AACzB,6CAA2B;AAC3B,6CAA2B"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { RuntimeEvent, EventRecorder } from './events';
|
|
2
|
+
export declare class FileEventRecorder implements EventRecorder {
|
|
3
|
+
private events;
|
|
4
|
+
private logFile;
|
|
5
|
+
private flushInterval;
|
|
6
|
+
constructor(logDir?: string);
|
|
7
|
+
record(event: RuntimeEvent): Promise<void>;
|
|
8
|
+
flush(): Promise<void>;
|
|
9
|
+
getEvents(executionId?: string): RuntimeEvent[];
|
|
10
|
+
}
|
|
11
|
+
export declare const createEvent: (executionId: string, type: RuntimeEvent["type"], data: RuntimeEvent["data"], metadata?: RuntimeEvent["metadata"]) => RuntimeEvent;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.createEvent = exports.FileEventRecorder = void 0;
|
|
7
|
+
const promises_1 = __importDefault(require("fs/promises"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const crypto_1 = require("crypto");
|
|
10
|
+
class FileEventRecorder {
|
|
11
|
+
events = [];
|
|
12
|
+
logFile;
|
|
13
|
+
flushInterval = 1000;
|
|
14
|
+
constructor(logDir = '.yuangs_events') {
|
|
15
|
+
this.logFile = path_1.default.join(logDir, `events_${Date.now()}.jsonl`);
|
|
16
|
+
}
|
|
17
|
+
async record(event) {
|
|
18
|
+
this.events.push(event);
|
|
19
|
+
if (this.events.length >= this.flushInterval) {
|
|
20
|
+
await this.flush();
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
async flush() {
|
|
24
|
+
if (this.events.length === 0)
|
|
25
|
+
return;
|
|
26
|
+
const logDir = path_1.default.dirname(this.logFile);
|
|
27
|
+
await promises_1.default.mkdir(logDir, { recursive: true });
|
|
28
|
+
const content = this.events
|
|
29
|
+
.map(e => JSON.stringify(e))
|
|
30
|
+
.join('\n') + '\n';
|
|
31
|
+
await promises_1.default.appendFile(this.logFile, content, 'utf8');
|
|
32
|
+
this.events = [];
|
|
33
|
+
}
|
|
34
|
+
getEvents(executionId) {
|
|
35
|
+
if (!executionId) {
|
|
36
|
+
return [...this.events];
|
|
37
|
+
}
|
|
38
|
+
return this.events.filter(e => e.executionId === executionId);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
exports.FileEventRecorder = FileEventRecorder;
|
|
42
|
+
const createEvent = (executionId, type, data, metadata) => ({
|
|
43
|
+
id: (0, crypto_1.randomUUID)(),
|
|
44
|
+
timestamp: Date.now(),
|
|
45
|
+
executionId,
|
|
46
|
+
type,
|
|
47
|
+
data,
|
|
48
|
+
metadata
|
|
49
|
+
});
|
|
50
|
+
exports.createEvent = createEvent;
|
|
51
|
+
//# sourceMappingURL=recorder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recorder.js","sourceRoot":"","sources":["../../../src/agent/replay/recorder.ts"],"names":[],"mappings":";;;;;;AACA,2DAA6B;AAC7B,gDAAwB;AACxB,mCAAoC;AAEpC,MAAa,iBAAiB;IACpB,MAAM,GAAmB,EAAE,CAAC;IAC5B,OAAO,CAAS;IAChB,aAAa,GAAW,IAAI,CAAC;IAErC,YAAY,SAAiB,gBAAgB;QAC3C,IAAI,CAAC,OAAO,GAAG,cAAI,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACjE,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAAmB;QAC9B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAExB,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YAC7C,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QACrB,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAErC,MAAM,MAAM,GAAG,cAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC1C,MAAM,kBAAE,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE5C,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM;aACxB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;aAC3B,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;QAErB,MAAM,kBAAE,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QACnD,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;IACnB,CAAC;IAED,SAAS,CAAC,WAAoB;QAC5B,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;QAC1B,CAAC;QAED,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,WAAW,CAAC,CAAC;IAChE,CAAC;CACF;AAtCD,8CAsCC;AAEM,MAAM,WAAW,GAAG,CACzB,WAAmB,EACnB,IAA0B,EAC1B,IAA0B,EAC1B,QAAmC,EACrB,EAAE,CAAC,CAAC;IAClB,EAAE,EAAE,IAAA,mBAAU,GAAE;IAChB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;IACrB,WAAW;IACX,IAAI;IACJ,IAAI;IACJ,QAAQ;CACT,CAAC,CAAC;AAZU,QAAA,WAAW,eAYrB"}
|