qwen-base 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +183 -0
- package/bin/install.js +227 -0
- package/package.json +42 -0
- package/src/commands/audit-claude-md.md +44 -0
- package/src/commands/audit-claude.md +45 -0
- package/src/commands/audit.md +33 -0
- package/src/commands/carl-hygiene.md +33 -0
- package/src/commands/groom.md +35 -0
- package/src/commands/history.md +27 -0
- package/src/commands/orientation/tasks/deep-why.md +132 -0
- package/src/commands/orientation/tasks/elevator-pitch.md +115 -0
- package/src/commands/orientation/tasks/initiatives.md +98 -0
- package/src/commands/orientation/tasks/key-values.md +130 -0
- package/src/commands/orientation/tasks/new-orientation.md +162 -0
- package/src/commands/orientation/tasks/north-star.md +97 -0
- package/src/commands/orientation/tasks/project-mapping.md +103 -0
- package/src/commands/orientation/tasks/reorientation.md +96 -0
- package/src/commands/orientation/tasks/surface-vision.md +113 -0
- package/src/commands/orientation/tasks/task-seeding.md +93 -0
- package/src/commands/orientation/templates/operator-json.md +88 -0
- package/src/commands/orientation.md +87 -0
- package/src/commands/pulse.md +33 -0
- package/src/commands/scaffold.md +33 -0
- package/src/commands/status.md +28 -0
- package/src/commands/surface-convert.md +35 -0
- package/src/commands/surface-create.md +34 -0
- package/src/commands/surface-list.md +27 -0
- package/src/commands/weekly-domain.md +34 -0
- package/src/commands/weekly.md +39 -0
- package/src/framework/context/base-principles.md +69 -0
- package/src/framework/frameworks/audit-strategies.md +53 -0
- package/src/framework/frameworks/claude-config-alignment.md +256 -0
- package/src/framework/frameworks/claudemd-strategy.md +158 -0
- package/src/framework/frameworks/satellite-registration.md +44 -0
- package/src/framework/tasks/audit-claude-md.md +171 -0
- package/src/framework/tasks/audit-claude.md +330 -0
- package/src/framework/tasks/audit.md +64 -0
- package/src/framework/tasks/carl-hygiene.md +142 -0
- package/src/framework/tasks/groom.md +157 -0
- package/src/framework/tasks/history.md +34 -0
- package/src/framework/tasks/pulse.md +83 -0
- package/src/framework/tasks/scaffold.md +389 -0
- package/src/framework/tasks/status.md +35 -0
- package/src/framework/tasks/surface-convert.md +143 -0
- package/src/framework/tasks/surface-create.md +184 -0
- package/src/framework/tasks/surface-list.md +42 -0
- package/src/framework/tasks/weekly-domain-create.md +173 -0
- package/src/framework/tasks/weekly.md +347 -0
- package/src/framework/templates/claudemd-template.md +102 -0
- package/src/framework/templates/workspace-json.md +96 -0
- package/src/framework/utils/scan-claude-dirs.py +549 -0
- package/src/hooks/_template.py +130 -0
- package/src/hooks/active-hook.py +178 -0
- package/src/hooks/apex-insights.py +169 -0
- package/src/hooks/backlog-hook.py +115 -0
- package/src/hooks/base-pulse-check.py +216 -0
- package/src/hooks/operator.py +53 -0
- package/src/hooks/psmm-injector.py +67 -0
- package/src/hooks/satellite-detection.py +320 -0
- package/src/packages/base-mcp/index.js +119 -0
- package/src/packages/base-mcp/package.json +10 -0
- package/src/packages/base-mcp/tools/entities.js +228 -0
- package/src/packages/base-mcp/tools/operator.js +106 -0
- package/src/packages/base-mcp/tools/projects.js +324 -0
- package/src/packages/base-mcp/tools/psmm.js +206 -0
- package/src/packages/base-mcp/tools/satellite.js +243 -0
- package/src/packages/base-mcp/tools/state.js +201 -0
- package/src/packages/base-mcp/tools/validate.js +121 -0
- package/src/skill/base.md +110 -0
- package/src/templates/operator.json +66 -0
- package/src/templates/workspace.json +76 -0
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight schema validation for BASE data surfaces.
|
|
3
|
+
* No external dependencies — enforces required fields and basic structure
|
|
4
|
+
* based on schemas/*.schema.json definitions.
|
|
5
|
+
*
|
|
6
|
+
* Validates on write to catch data corruption early.
|
|
7
|
+
* Logs warnings rather than throwing — defensive, won't block operations.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
function debugLog(...args) {
|
|
11
|
+
console.error('[BASE:validate]', new Date().toISOString(), ...args);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// ============================================================
|
|
15
|
+
// SCHEMA DEFINITIONS (derived from schemas/*.schema.json)
|
|
16
|
+
// ============================================================
|
|
17
|
+
|
|
18
|
+
const SCHEMAS = {
|
|
19
|
+
projects: {
|
|
20
|
+
requiredRoot: ['items'],
|
|
21
|
+
itemFields: ['id', 'title', 'type', 'status', 'priority', 'created_at', 'updated_at'],
|
|
22
|
+
validTypes: ['initiative', 'project', 'task'],
|
|
23
|
+
validStatuses: ['backlog', 'todo', 'in_progress', 'blocked', 'in_review', 'completed', 'deferred', 'archived'],
|
|
24
|
+
validPriorities: ['urgent', 'high', 'medium', 'low', 'ongoing'],
|
|
25
|
+
idPattern: /^(INI|PRJ|TSK)-\d{3,}$/
|
|
26
|
+
},
|
|
27
|
+
entities: {
|
|
28
|
+
requiredRoot: ['entities'],
|
|
29
|
+
itemFields: ['id', 'name', 'type', 'created_at', 'updated_at'],
|
|
30
|
+
validTypes: ['person', 'organization'],
|
|
31
|
+
idPattern: /^ENT-\d{3,}$/
|
|
32
|
+
},
|
|
33
|
+
state: {
|
|
34
|
+
requiredRoot: ['groom', 'drift', 'areas'],
|
|
35
|
+
requiredGroom: ['cadence'],
|
|
36
|
+
validCadences: ['daily', 'weekly', 'bi-weekly', 'monthly'],
|
|
37
|
+
validAreaStatuses: ['current', 'stale', 'critical']
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
// ============================================================
|
|
42
|
+
// VALIDATORS
|
|
43
|
+
// ============================================================
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Validate a data surface before writing.
|
|
47
|
+
* Returns { valid: boolean, warnings: string[] }
|
|
48
|
+
*/
|
|
49
|
+
export function validateSurface(surfaceName, data) {
|
|
50
|
+
const schema = SCHEMAS[surfaceName];
|
|
51
|
+
if (!schema) {
|
|
52
|
+
return { valid: true, warnings: [] };
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const warnings = [];
|
|
56
|
+
|
|
57
|
+
// Check required root fields
|
|
58
|
+
if (schema.requiredRoot) {
|
|
59
|
+
for (const field of schema.requiredRoot) {
|
|
60
|
+
if (data[field] === undefined) {
|
|
61
|
+
warnings.push(`Missing required root field: ${field}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Validate items array (projects, entities)
|
|
67
|
+
if (schema.itemFields && Array.isArray(data.items || data.entities)) {
|
|
68
|
+
const items = data.items || data.entities;
|
|
69
|
+
for (let i = 0; i < items.length; i++) {
|
|
70
|
+
const item = items[i];
|
|
71
|
+
for (const field of schema.itemFields) {
|
|
72
|
+
if (item[field] === undefined) {
|
|
73
|
+
warnings.push(`Item ${item.id || `[${i}]`}: missing required field '${field}'`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Validate ID pattern
|
|
78
|
+
if (schema.idPattern && item.id && !schema.idPattern.test(item.id)) {
|
|
79
|
+
warnings.push(`Item ${item.id}: ID does not match pattern ${schema.idPattern}`);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Validate enum fields
|
|
83
|
+
if (schema.validTypes && item.type && !schema.validTypes.includes(item.type)) {
|
|
84
|
+
warnings.push(`Item ${item.id || `[${i}]`}: invalid type '${item.type}'`);
|
|
85
|
+
}
|
|
86
|
+
if (schema.validStatuses && item.status && !schema.validStatuses.includes(item.status)) {
|
|
87
|
+
warnings.push(`Item ${item.id || `[${i}]`}: invalid status '${item.status}'`);
|
|
88
|
+
}
|
|
89
|
+
if (schema.validPriorities && item.priority && !schema.validPriorities.includes(item.priority)) {
|
|
90
|
+
warnings.push(`Item ${item.id || `[${i}]`}: invalid priority '${item.priority}'`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// State-specific validation
|
|
96
|
+
if (surfaceName === 'state') {
|
|
97
|
+
if (data.groom && schema.requiredGroom) {
|
|
98
|
+
for (const field of schema.requiredGroom) {
|
|
99
|
+
if (data.groom[field] === undefined) {
|
|
100
|
+
warnings.push(`groom: missing required field '${field}'`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (data.groom.cadence && !schema.validCadences.includes(data.groom.cadence)) {
|
|
104
|
+
warnings.push(`groom: invalid cadence '${data.groom.cadence}'`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
if (data.areas) {
|
|
108
|
+
for (const [areaName, area] of Object.entries(data.areas)) {
|
|
109
|
+
if (area.status && !schema.validAreaStatuses.includes(area.status)) {
|
|
110
|
+
warnings.push(`area '${areaName}': invalid status '${area.status}'`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (warnings.length > 0) {
|
|
117
|
+
debugLog(`Validation warnings for ${surfaceName}:`, warnings);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return { valid: warnings.length === 0, warnings };
|
|
121
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: base
|
|
3
|
+
type: suite
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
category: workspace-orchestration
|
|
6
|
+
description: "Builder's Automated State Engine — workspace lifecycle management for Claude Code. Scaffold, audit, groom, and maintain AI builder workspaces. Manage data surfaces for structured context injection. Use when user mentions workspace setup, cleanup, organization, maintenance, grooming, auditing workspace health, surfaces, or BASE."
|
|
7
|
+
allowed-tools: [Read, Write, Glob, Grep, Edit, Bash, Agent, AskUserQuestion]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
<activation>
|
|
11
|
+
|
|
12
|
+
## What
|
|
13
|
+
BASE (Builder's Automated State Engine) manages the lifecycle of a Claude Code workspace. It scaffolds new workspaces, audits existing ones, runs structured grooming cycles, and maintains workspace health through automated drift detection.
|
|
14
|
+
|
|
15
|
+
## When to Use
|
|
16
|
+
- User says "base", "workspace", "cleanup", "organize", "audit my workspace", "groom", "surface", "create a surface"
|
|
17
|
+
- User wants to set up a new workspace from scratch
|
|
18
|
+
- User wants to optimize or clean up an existing workspace
|
|
19
|
+
- User asks about workspace health, staleness, or drift
|
|
20
|
+
- Session start hook detects overdue grooming
|
|
21
|
+
- User wants to review workspace evolution history
|
|
22
|
+
|
|
23
|
+
## Not For
|
|
24
|
+
- Project-level build orchestration (that's PAUL)
|
|
25
|
+
- Session-level rule management (that's CARL)
|
|
26
|
+
- Code quality auditing (that's AEGIS)
|
|
27
|
+
- Skill/tool creation (that's Skillsmith)
|
|
28
|
+
|
|
29
|
+
</activation>
|
|
30
|
+
|
|
31
|
+
<persona>
|
|
32
|
+
|
|
33
|
+
## Role
|
|
34
|
+
Workspace operations engineer. Knows the territory, tracks what's drifting, enforces maintenance cadence. Tactical, not theoretical.
|
|
35
|
+
|
|
36
|
+
## Style
|
|
37
|
+
- Direct, structured, checklist-driven
|
|
38
|
+
- Presents health dashboards and drift scores
|
|
39
|
+
- Asks focused questions during grooming (voice-friendly)
|
|
40
|
+
- Never skips areas — systematic coverage
|
|
41
|
+
- Recommends, doesn't dictate
|
|
42
|
+
|
|
43
|
+
## Expertise
|
|
44
|
+
- Workspace architecture and file organization
|
|
45
|
+
- Context document lifecycle (projects.json, state.json, entities.json)
|
|
46
|
+
- Tool and configuration management
|
|
47
|
+
- Drift detection and prevention patterns
|
|
48
|
+
- Claude Code ecosystem (PAUL, CARL, AEGIS, Skillsmith integration)
|
|
49
|
+
|
|
50
|
+
</persona>
|
|
51
|
+
|
|
52
|
+
<commands>
|
|
53
|
+
|
|
54
|
+
| Command | Description | Routes To |
|
|
55
|
+
|---------|------------|-----------|
|
|
56
|
+
| `/base:pulse` | Daily activation — workspace health briefing | `@{~/.qwen/commands/qwen-base/tasks/pulse.md}` |
|
|
57
|
+
| `/base:groom` | Weekly maintenance cycle | `@{~/.qwen/commands/qwen-base/tasks/groom.md}` |
|
|
58
|
+
| `/base:audit` | Deep workspace optimization | `@{~/.qwen/commands/qwen-base/tasks/audit.md}` |
|
|
59
|
+
| `/base:scaffold` | Set up BASE in a new workspace | `@{~/.qwen/commands/qwen-base/tasks/scaffold.md}` |
|
|
60
|
+
| `/base:status` | Quick health check (one-liner) | `@{~/.qwen/commands/qwen-base/tasks/status.md}` |
|
|
61
|
+
| `/base:history` | Workspace evolution timeline | `@{~/.qwen/commands/qwen-base/tasks/history.md}` |
|
|
62
|
+
| `/base:audit-claude-md` | Audit CLAUDE.md, generate recommended version | `@{~/.qwen/commands/qwen-base/tasks/audit-claude-md.md}` |
|
|
63
|
+
| `/base:carl-hygiene` | CARL domain maintenance and rule review | `@{~/.qwen/commands/qwen-base/tasks/carl-hygiene.md}` |
|
|
64
|
+
| `/base:surface create` | Create a new data surface (guided) | `@{~/.qwen/commands/qwen-base/tasks/surface-create.md}` |
|
|
65
|
+
| `/base:surface convert` | Convert markdown file to data surface | `@{~/.qwen/commands/qwen-base/tasks/surface-convert.md}` |
|
|
66
|
+
| `/base:surface list` | Show all registered surfaces | `@{~/.qwen/commands/qwen-base/tasks/surface-list.md}` |
|
|
67
|
+
|
|
68
|
+
</commands>
|
|
69
|
+
|
|
70
|
+
<routing>
|
|
71
|
+
|
|
72
|
+
## Always Load
|
|
73
|
+
- `@{~/.qwen/commands/qwen-base/context/base-principles.md}` — Core workspace management principles
|
|
74
|
+
- `@{~/.qwen/commands/qwen-base/frameworks/audit-strategies.md}` — Reusable audit strategy definitions
|
|
75
|
+
|
|
76
|
+
## Load on Command
|
|
77
|
+
- `@{~/.qwen/commands/qwen-base/tasks/pulse.md}` — on `/base:pulse`
|
|
78
|
+
- `@{~/.qwen/commands/qwen-base/tasks/groom.md}` — on `/base:groom`
|
|
79
|
+
- `@{~/.qwen/commands/qwen-base/tasks/audit.md}` — on `/base:audit`
|
|
80
|
+
- `@{~/.qwen/commands/qwen-base/tasks/scaffold.md}` — on `/base:scaffold`
|
|
81
|
+
- `@{~/.qwen/commands/qwen-base/tasks/status.md}` — on `/base:status`
|
|
82
|
+
- `@{~/.qwen/commands/qwen-base/tasks/history.md}` — on `/base:history`
|
|
83
|
+
- `@{~/.qwen/commands/qwen-base/tasks/carl-hygiene.md}` — on `/base:carl-hygiene`
|
|
84
|
+
- `@{~/.qwen/commands/qwen-base/tasks/surface-create.md}` — on `/base:surface create`
|
|
85
|
+
- `@{~/.qwen/commands/qwen-base/tasks/surface-convert.md}` — on `/base:surface convert`
|
|
86
|
+
- `@{~/.qwen/commands/qwen-base/tasks/surface-list.md}` — on `/base:surface list`
|
|
87
|
+
|
|
88
|
+
## Load on Demand
|
|
89
|
+
- `@{~/.qwen/commands/qwen-base/templates/workspace-json.md}` — When generating workspace.json
|
|
90
|
+
- `@{~/.qwen/commands/qwen-base/frameworks/satellite-registration.md}` — When handling PAUL project registration
|
|
91
|
+
|
|
92
|
+
</routing>
|
|
93
|
+
|
|
94
|
+
<greeting>
|
|
95
|
+
|
|
96
|
+
BASE loaded. Builder's Automated State Engine.
|
|
97
|
+
|
|
98
|
+
Available commands:
|
|
99
|
+
- `/base:pulse` — What's the state of my workspace?
|
|
100
|
+
- `/base:groom` — Run weekly maintenance
|
|
101
|
+
- `/base:audit` — Deep optimization session
|
|
102
|
+
- `/base:scaffold` — Set up BASE in a new workspace
|
|
103
|
+
- `/base:status` — Quick health check
|
|
104
|
+
- `/base:history` — Workspace evolution timeline
|
|
105
|
+
- `/base:surface create` — Create a new data surface
|
|
106
|
+
- `/base:surface list` — Show registered surfaces
|
|
107
|
+
|
|
108
|
+
What do you need?
|
|
109
|
+
|
|
110
|
+
</greeting>
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"last_updated": null,
|
|
4
|
+
"hook_active": true,
|
|
5
|
+
"operator": {
|
|
6
|
+
"entity_id": null,
|
|
7
|
+
"name": null
|
|
8
|
+
},
|
|
9
|
+
"deep_why": {
|
|
10
|
+
"layers": [
|
|
11
|
+
{
|
|
12
|
+
"level": 1,
|
|
13
|
+
"question": "Why do you do what you do?",
|
|
14
|
+
"answer": null
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"level": 2,
|
|
18
|
+
"question": "But why does that matter?",
|
|
19
|
+
"answer": null
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"level": 3,
|
|
23
|
+
"question": "But why?",
|
|
24
|
+
"answer": null
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"level": 4,
|
|
28
|
+
"question": "Why does that drive you more than anything else?",
|
|
29
|
+
"answer": null
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"level": 5,
|
|
33
|
+
"question": "If everything else was stripped away, what's left?",
|
|
34
|
+
"answer": null
|
|
35
|
+
}
|
|
36
|
+
],
|
|
37
|
+
"statement": null,
|
|
38
|
+
"completed_at": null
|
|
39
|
+
},
|
|
40
|
+
"north_star": {
|
|
41
|
+
"metric": null,
|
|
42
|
+
"timeframe": null,
|
|
43
|
+
"rationale": null,
|
|
44
|
+
"completed_at": null
|
|
45
|
+
},
|
|
46
|
+
"key_values": {
|
|
47
|
+
"values": [],
|
|
48
|
+
"completed_at": null
|
|
49
|
+
},
|
|
50
|
+
"elevator_pitch": {
|
|
51
|
+
"pitch": null,
|
|
52
|
+
"floors": {
|
|
53
|
+
"floor_1": null,
|
|
54
|
+
"floor_2": null,
|
|
55
|
+
"floor_3": null,
|
|
56
|
+
"floor_4": null
|
|
57
|
+
},
|
|
58
|
+
"completed_at": null
|
|
59
|
+
},
|
|
60
|
+
"surface_vision": {
|
|
61
|
+
"scenes": [],
|
|
62
|
+
"summary": null,
|
|
63
|
+
"completed_at": null
|
|
64
|
+
},
|
|
65
|
+
"extensions": {}
|
|
66
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{
|
|
2
|
+
"workspace": "{workspace-name}",
|
|
3
|
+
"created": "{YYYY-MM-DD}",
|
|
4
|
+
"groom_cadence": "weekly",
|
|
5
|
+
"groom_day": "friday",
|
|
6
|
+
"areas": {
|
|
7
|
+
"working-memory": {
|
|
8
|
+
"type": "working-memory",
|
|
9
|
+
"description": "Core context documents that AI reads every session",
|
|
10
|
+
"paths": [
|
|
11
|
+
".base/data/projects.json"
|
|
12
|
+
],
|
|
13
|
+
"groom": "weekly",
|
|
14
|
+
"audit": {
|
|
15
|
+
"strategy": "staleness",
|
|
16
|
+
"config": {
|
|
17
|
+
"threshold_days": 7
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"projects": {
|
|
22
|
+
"type": "directory",
|
|
23
|
+
"description": "Project documentation and planning",
|
|
24
|
+
"paths": [
|
|
25
|
+
"projects/"
|
|
26
|
+
],
|
|
27
|
+
"groom": "monthly",
|
|
28
|
+
"audit": {
|
|
29
|
+
"strategy": "classify",
|
|
30
|
+
"config": {
|
|
31
|
+
"states": ["active", "archive", "delete"],
|
|
32
|
+
"archive_path": "projects/_archive/"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"tools": {
|
|
37
|
+
"type": "config-cross-ref",
|
|
38
|
+
"description": "MCP servers, personal tools, shareable tools",
|
|
39
|
+
"paths": [
|
|
40
|
+
"tools/"
|
|
41
|
+
],
|
|
42
|
+
"groom": "monthly",
|
|
43
|
+
"audit": {
|
|
44
|
+
"strategy": "cross-reference",
|
|
45
|
+
"config": {
|
|
46
|
+
"config_file": ".mcp.json"
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
"system-layer": {
|
|
51
|
+
"type": "system-layer",
|
|
52
|
+
"description": "Claude Code commands, hooks, skills, CARL domains",
|
|
53
|
+
"paths": [
|
|
54
|
+
".qwen/commands/",
|
|
55
|
+
".qwen/hooks/",
|
|
56
|
+
".qwen/skills/",
|
|
57
|
+
".carl/"
|
|
58
|
+
],
|
|
59
|
+
"groom": "monthly",
|
|
60
|
+
"audit": {
|
|
61
|
+
"strategy": "dead-code",
|
|
62
|
+
"config": {
|
|
63
|
+
"reference_check": true
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
"carl_hygiene": {
|
|
69
|
+
"proactive": true,
|
|
70
|
+
"cadence": "monthly",
|
|
71
|
+
"staleness_threshold_days": 60,
|
|
72
|
+
"max_rules_per_domain": 15,
|
|
73
|
+
"last_run": null
|
|
74
|
+
},
|
|
75
|
+
"satellites": {}
|
|
76
|
+
}
|