@amsterdamdatalabs/enact-extensions 0.1.10 → 0.1.24
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 +11 -12
- package/dist/create/claude.d.ts.map +1 -1
- package/dist/create/claude.js +6 -2
- package/dist/create/claude.js.map +1 -1
- package/dist/create/cursor.d.ts.map +1 -1
- package/dist/create/cursor.js +6 -2
- package/dist/create/cursor.js.map +1 -1
- package/dist/create/enact.js +1 -1
- package/dist/create/enact.js.map +1 -1
- package/dist/create/index.d.ts +4 -3
- package/dist/create/index.d.ts.map +1 -1
- package/dist/create/index.js +9 -2
- package/dist/create/index.js.map +1 -1
- package/dist/index.d.ts +9 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -4
- package/dist/index.js.map +1 -1
- package/dist/install.d.ts +5 -0
- package/dist/install.d.ts.map +1 -1
- package/dist/install.js +91 -11
- package/dist/install.js.map +1 -1
- package/dist/internal/agents.d.ts +25 -1
- package/dist/internal/agents.d.ts.map +1 -1
- package/dist/internal/agents.js +81 -4
- package/dist/internal/agents.js.map +1 -1
- package/dist/internal/claude.d.ts +49 -0
- package/dist/internal/claude.d.ts.map +1 -1
- package/dist/internal/claude.js +166 -1
- package/dist/internal/claude.js.map +1 -1
- package/dist/internal/platform.d.ts +11 -1
- package/dist/internal/platform.d.ts.map +1 -1
- package/dist/internal/platform.js +58 -1
- package/dist/internal/platform.js.map +1 -1
- package/dist/internal/types.d.ts +2 -1
- package/dist/internal/types.d.ts.map +1 -1
- package/dist/principles.d.ts +28 -0
- package/dist/principles.d.ts.map +1 -0
- package/dist/principles.js +159 -0
- package/dist/principles.js.map +1 -0
- package/extensions/dev-state/.agents/plugin.json +2 -1
- package/extensions/enact-context/.agents/plugin.json +2 -1
- package/extensions/enact-context/hooks/hooks.json +0 -10
- package/extensions/enact-context/skills/enact-context/SKILL.md +14 -12
- package/extensions/enact-context/skills/enact-context/scripts/install.sh +7 -7
- package/extensions/enact-core/.agents/plugin.json +2 -1
- package/extensions/enact-core/OPERATING-PRINCIPLES.md +7 -0
- package/extensions/enact-core/hooks/hooks.json +12 -0
- package/extensions/enact-evolve/.agents/plugin.json +47 -0
- package/extensions/enact-evolve/agents/evolve-session-analyst.toml +37 -0
- package/extensions/enact-evolve/skills/session-analysis/SKILL.md +98 -0
- package/extensions/enact-evolve/skills/session-analysis/scripts/run-evolve-analysis.sh +343 -0
- package/extensions/enact-factory/.agents/plugin.json +2 -1
- package/extensions/enact-factory/agents/architect.toml +9 -5
- package/extensions/enact-factory/agents/code-reviewer.toml +9 -5
- package/extensions/enact-factory/agents/critic.toml +9 -5
- package/extensions/enact-factory/agents/executor.toml +4 -1
- package/extensions/enact-factory/agents/explore.toml +4 -1
- package/extensions/enact-factory/agents/planner.toml +4 -1
- package/extensions/enact-factory/agents/verifier.toml +9 -5
- package/extensions/enact-factory/skills/advisor/SKILL.md +82 -0
- package/extensions/enact-factory/skills/ai-slop-cleaner/SKILL.md +6 -1
- package/extensions/enact-factory/skills/autonomous-runner/SKILL.md +347 -0
- package/extensions/enact-factory/skills/azdo-ci-strategy/SKILL.md +62 -15
- package/extensions/enact-factory/skills/committee/SKILL.md +80 -0
- package/extensions/enact-factory/skills/deep-interview/SKILL.md +9 -13
- package/extensions/enact-factory/skills/drive-loop/SKILL.md +161 -31
- package/extensions/enact-factory/skills/drive-loop/references/contract-schema.md +26 -6
- package/extensions/enact-factory/skills/handoff/SKILL.md +72 -0
- package/extensions/enact-factory/skills/hyperplan/SKILL.md +11 -3
- package/extensions/enact-factory/skills/looplan/SKILL.md +34 -17
- package/extensions/enact-factory/skills/plan/SKILL.md +40 -8
- package/extensions/enact-factory/skills/remove-deadcode/SKILL.md +6 -1
- package/extensions/enact-factory/skills/research/SKILL.md +14 -4
- package/extensions/enact-factory/skills/review/SKILL.md +21 -2
- package/extensions/enact-factory/skills/security-research/SKILL.md +5 -2
- package/extensions/enact-factory/skills/tdd/SKILL.md +7 -1
- package/extensions/enact-factory/skills/testing-strategy/SKILL.md +5 -0
- package/extensions/enact-factory/skills/trace/SKILL.md +5 -0
- package/extensions/enact-factory/skills/ultraqa/SKILL.md +21 -15
- package/extensions/enact-factory/skills/work-with-workitem/SKILL.md +5 -0
- package/extensions/enact-factory/skills/workitem-triage/SKILL.md +5 -0
- package/extensions/enact-loop/.agents/plugin.json +5 -4
- package/extensions/enact-loop/scripts/validate.mjs +123 -0
- package/extensions/enact-loop/skills/enact-loop/SKILL.md +189 -30
- package/extensions/enact-wiki/.agents/plugin.json +2 -1
- package/extensions/net-revenue-management/.agents/plugin.json +2 -1
- package/extensions/plugin-dev/.agents/plugin.json +2 -1
- package/extensions/plugin-dev/skills/start/SKILL.md +3 -3
- package/package.json +1 -1
- package/scripts/check-hooks.mjs +5 -5
- package/scripts/check-principles.mjs +19 -4
- package/scripts/enact-extensions.mjs +237 -90
- package/scripts/lib/hooks.mjs +61 -217
- package/scripts/lib/migrate-artifacts.mjs +144 -0
- package/scripts/lib/principles.mjs +109 -0
- package/scripts/lib/provision-mcp.mjs +1 -1
- package/scripts/lib/run-install.mjs +72 -2
- package/scripts/lib/run-prune.mjs +23 -2
- package/scripts/lib/run-sync.mjs +4 -1
- package/scripts/postinstall.mjs +6 -6
- package/scripts/setup-enact-context.sh +20 -15
- package/spec/codex.json +5 -0
- package/spec/enact.json +3 -3
- package/spec/enact.md +1 -4
- package/spec/index.json +1 -1
- package/extensions/enact-operator/.agents/plugin.json +0 -56
- package/extensions/enact-operator/.app.json +0 -3
- package/extensions/enact-operator/.mcp.json +0 -10
- package/extensions/enact-operator/_taxonomy.md +0 -86
- package/extensions/enact-operator/agents/README.md +0 -5
- package/extensions/enact-operator/agents/architect.toml +0 -25
- package/extensions/enact-operator/agents/code-reviewer.toml +0 -24
- package/extensions/enact-operator/agents/critic.toml +0 -30
- package/extensions/enact-operator/agents/executor.toml +0 -24
- package/extensions/enact-operator/agents/explore.toml +0 -23
- package/extensions/enact-operator/agents/planner.toml +0 -24
- package/extensions/enact-operator/agents/verifier.toml +0 -24
- package/extensions/enact-operator/docs/skill-variants.md +0 -44
- package/extensions/enact-operator/hooks/hooks.json +0 -91
- package/extensions/enact-operator/skills/ai-slop-cleaner/SKILL.md +0 -50
- package/extensions/enact-operator/skills/analyze/SKILL.md +0 -91
- package/extensions/enact-operator/skills/ask/SKILL.md +0 -47
- package/extensions/enact-operator/skills/autopilot/SKILL.md +0 -170
- package/extensions/enact-operator/skills/autoresearch-goal/SKILL.md +0 -79
- package/extensions/enact-operator/skills/cancel/SKILL.md +0 -99
- package/extensions/enact-operator/skills/configure-notifications/SKILL.md +0 -77
- package/extensions/enact-operator/skills/deep-interview/SKILL.md +0 -80
- package/extensions/enact-operator/skills/doctor/SKILL.md +0 -48
- package/extensions/enact-operator/skills/hud/SKILL.md +0 -49
- package/extensions/enact-operator/skills/hyperplan/SKILL.md +0 -47
- package/extensions/enact-operator/skills/plan/SKILL.md +0 -78
- package/extensions/enact-operator/skills/ralph/SKILL.md +0 -201
- package/extensions/enact-operator/skills/ralph/gemini.md +0 -18
- package/extensions/enact-operator/skills/ralplan/SKILL.md +0 -151
- package/extensions/enact-operator/skills/remove-deadcode/SKILL.md +0 -45
- package/extensions/enact-operator/skills/research/SKILL.md +0 -74
- package/extensions/enact-operator/skills/review/SKILL.md +0 -58
- package/extensions/enact-operator/skills/security-research/SKILL.md +0 -54
- package/extensions/enact-operator/skills/setup/SKILL.md +0 -91
- package/extensions/enact-operator/skills/setup/scripts/install.sh +0 -50
- package/extensions/enact-operator/skills/skill/SKILL.md +0 -82
- package/extensions/enact-operator/skills/tdd/SKILL.md +0 -59
- package/extensions/enact-operator/skills/team/SKILL.md +0 -199
- package/extensions/enact-operator/skills/trace/SKILL.md +0 -41
- package/extensions/enact-operator/skills/ultragoal/SKILL.md +0 -99
- package/extensions/enact-operator/skills/ultraqa/SKILL.md +0 -113
- package/extensions/enact-operator/skills/ultrawork/SKILL.md +0 -145
- package/extensions/enact-operator/skills/ultrawork/planner.md +0 -28
- package/extensions/enact-operator/skills/wiki/SKILL.md +0 -41
- package/extensions/enact-operator/skills/work-with-workitem/SKILL.md +0 -51
- /package/extensions/{enact-operator → enact-evolve}/assets/icon.png +0 -0
- /package/extensions/{enact-operator → enact-evolve}/assets/logo.png +0 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: session-analysis
|
|
3
|
+
description: This skill should be used when the user asks to analyze, audit, evaluate, or synthesize Codex, Claude, or Factory session transcripts, rollout JSONL files, tool/MCP call behavior, hook evidence, context injection, token usage, or candidate improvements with enact-evolve. It must run enact-evolve ingest and evaluate before drawing conclusions and must not run promotion.
|
|
4
|
+
argument-hint: "--surface <codex|claude|factory> --session <path-or-id> [--watchdog <path>] [--out <dir>]"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Enact Evolve Session Analysis
|
|
8
|
+
|
|
9
|
+
Use this workflow for session forensics. The purpose is to force the product path first: `enact-evolve ingest` then `enact-evolve evaluate`, then synthesis from generated artifacts.
|
|
10
|
+
|
|
11
|
+
## Non-Negotiables
|
|
12
|
+
|
|
13
|
+
- Use `enact-evolve` CLI artifacts as primary truth.
|
|
14
|
+
- Never run `enact-evolve promote`.
|
|
15
|
+
- Do not create Dream, wiki, extension, package patch, or promotion handoff artifacts.
|
|
16
|
+
- Do not rely on raw JSONL parsing until after ingest/evaluate has run.
|
|
17
|
+
- Label every raw transcript lookup as a cross-check, not primary evidence.
|
|
18
|
+
- If `hook_summary` or `hook_timeline` is empty, say the normalized evidence did not capture hook firings; do not infer that hooks did not fire.
|
|
19
|
+
|
|
20
|
+
## Inputs
|
|
21
|
+
|
|
22
|
+
Accept the same arguments as the helper script:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
${CLAUDE_PLUGIN_ROOT}/skills/session-analysis/scripts/run-evolve-analysis.sh \
|
|
26
|
+
--surface codex \
|
|
27
|
+
--session /path/to/session.jsonl
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Required:
|
|
31
|
+
- `--surface codex|claude|factory`
|
|
32
|
+
- `--session <path-or-id>`
|
|
33
|
+
|
|
34
|
+
Optional:
|
|
35
|
+
- `--watchdog <path>`
|
|
36
|
+
- `--out <dir>`
|
|
37
|
+
|
|
38
|
+
Default output:
|
|
39
|
+
`~/.enact/evolve/projects/<workspace-id>/analysis/<surface>-<safe-session-id>/`
|
|
40
|
+
|
|
41
|
+
The helper resolves `<workspace-id>` from the current working directory by calling `enact-evolve storage --json`, matching the cwd-bound `mcp .` pattern used by other Enact plugins. Pass `--out` only when an explicit non-default location is required.
|
|
42
|
+
|
|
43
|
+
## Workflow
|
|
44
|
+
|
|
45
|
+
1. Resolve the session source and surface.
|
|
46
|
+
- Use `codex` for files under `.codex/sessions` or rollout JSONL.
|
|
47
|
+
- Use `claude` for Claude transcript JSONL.
|
|
48
|
+
- Use `factory` only for supported factory scenarios.
|
|
49
|
+
- Treat the current working directory as the owning workspace for storage.
|
|
50
|
+
|
|
51
|
+
2. Run the helper script.
|
|
52
|
+
- Prefer the bundled script over handwritten CLI command sequences.
|
|
53
|
+
- The script verifies `enact-evolve`, resolves project-scoped analysis storage from cwd, writes session-specific artifacts, and refuses to continue if promotion artifacts are produced.
|
|
54
|
+
|
|
55
|
+
3. Read these generated artifacts:
|
|
56
|
+
- `session-evidence.jsonl`
|
|
57
|
+
- `metrics.jsonl`
|
|
58
|
+
- `candidate-improvements.jsonl`
|
|
59
|
+
- `trace-events.jsonl`
|
|
60
|
+
- `eval/session-evidence.jsonl`
|
|
61
|
+
- `eval/metrics.jsonl`
|
|
62
|
+
- `eval/candidate-improvements.jsonl`
|
|
63
|
+
- `eval/trace-events.jsonl`
|
|
64
|
+
- `<session-id>.md`
|
|
65
|
+
- `synthesis.md`
|
|
66
|
+
|
|
67
|
+
4. Synthesize from normalized evidence first.
|
|
68
|
+
- Use `tool_summary`, `tool_timeline`, `hook_summary`, `hook_timeline`, `context_summary`, `system_prompts`, `quality_metrics`, and `candidate_improvements`.
|
|
69
|
+
- Prefer the transcript markdown for readable chronology and context.
|
|
70
|
+
- Use raw JSONL only for fields that are not yet represented in normalized evidence, such as exact MCP `server/tool` pairs.
|
|
71
|
+
|
|
72
|
+
5. Report limitations.
|
|
73
|
+
- Empty hook summaries mean "not normalized/captured as hook events in evidence", not "did not happen."
|
|
74
|
+
- Missing prompt counts or context entries should be called out as evidence-shape limitations.
|
|
75
|
+
- If the helper fails because `enact-evolve` is missing, report the install/runtime issue before attempting manual analysis.
|
|
76
|
+
|
|
77
|
+
## Required Synthesis Shape
|
|
78
|
+
|
|
79
|
+
Return or update `synthesis.md` with these sections:
|
|
80
|
+
|
|
81
|
+
- `Session Identity`: surface, session id, source path, evidence id, output paths.
|
|
82
|
+
- `Pipeline Proof`: exact ingest/evaluate commands and generated artifact list.
|
|
83
|
+
- `Tool And MCP Analysis`: normalized tool summary first; raw MCP cross-check only if needed.
|
|
84
|
+
- `Hook Evidence`: hook timeline/summary and any explicit evidence limitation.
|
|
85
|
+
- `Context Injection`: system/developer/context entries, token usage, duplicate context, largest context blocks.
|
|
86
|
+
- `Candidate Summary`: counts by target family, notable source signals, extension-skill/rule/tool-description implications.
|
|
87
|
+
- `Findings`: what happened, what went wrong, and what the assistant should have done.
|
|
88
|
+
- `Follow-Up Recommendations`: implementation or workflow changes, explicitly excluding promotion unless the user separately requests it.
|
|
89
|
+
|
|
90
|
+
## Verification
|
|
91
|
+
|
|
92
|
+
After running the helper, verify:
|
|
93
|
+
- `session-evidence.jsonl` exists and has at least one record.
|
|
94
|
+
- `eval/metrics.jsonl` exists.
|
|
95
|
+
- `eval/candidate-improvements.jsonl` exists, even if empty.
|
|
96
|
+
- Transcript markdown exists.
|
|
97
|
+
- `synthesis.md` exists.
|
|
98
|
+
- No `promote/` directory exists under the output directory.
|
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
usage() {
|
|
5
|
+
cat <<'USAGE'
|
|
6
|
+
Usage:
|
|
7
|
+
run-evolve-analysis.sh --surface codex|claude|factory --session <path-or-id> [--watchdog <path>] [--out <dir>]
|
|
8
|
+
|
|
9
|
+
Runs enact-evolve ingest, enact-evolve evaluate, and writes synthesis.md.
|
|
10
|
+
This workflow does not run promotion.
|
|
11
|
+
USAGE
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
surface=""
|
|
15
|
+
session=""
|
|
16
|
+
watchdog=""
|
|
17
|
+
out=""
|
|
18
|
+
|
|
19
|
+
while [[ $# -gt 0 ]]; do
|
|
20
|
+
case "$1" in
|
|
21
|
+
--surface)
|
|
22
|
+
surface="${2:-}"
|
|
23
|
+
shift 2
|
|
24
|
+
;;
|
|
25
|
+
--session)
|
|
26
|
+
session="${2:-}"
|
|
27
|
+
shift 2
|
|
28
|
+
;;
|
|
29
|
+
--watchdog)
|
|
30
|
+
watchdog="${2:-}"
|
|
31
|
+
shift 2
|
|
32
|
+
;;
|
|
33
|
+
--out)
|
|
34
|
+
out="${2:-}"
|
|
35
|
+
shift 2
|
|
36
|
+
;;
|
|
37
|
+
-h|--help)
|
|
38
|
+
usage
|
|
39
|
+
exit 0
|
|
40
|
+
;;
|
|
41
|
+
*)
|
|
42
|
+
echo "Unknown argument: $1" >&2
|
|
43
|
+
usage >&2
|
|
44
|
+
exit 2
|
|
45
|
+
;;
|
|
46
|
+
esac
|
|
47
|
+
done
|
|
48
|
+
|
|
49
|
+
if [[ -z "$surface" || -z "$session" ]]; then
|
|
50
|
+
usage >&2
|
|
51
|
+
exit 2
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
case "$surface" in
|
|
55
|
+
codex|claude|factory)
|
|
56
|
+
;;
|
|
57
|
+
*)
|
|
58
|
+
echo "Invalid --surface: $surface" >&2
|
|
59
|
+
usage >&2
|
|
60
|
+
exit 2
|
|
61
|
+
;;
|
|
62
|
+
esac
|
|
63
|
+
|
|
64
|
+
if ! command -v enact-evolve >/dev/null 2>&1; then
|
|
65
|
+
echo "enact-evolve is required on PATH." >&2
|
|
66
|
+
exit 127
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
safe_session_id() {
|
|
70
|
+
local value="$1"
|
|
71
|
+
value="${value%/}"
|
|
72
|
+
value="${value##*/}"
|
|
73
|
+
value="${value:-session}"
|
|
74
|
+
printf '%s' "$value" | sed -E 's/[^A-Za-z0-9._-]+/-/g; s/^-+//; s/-+$//'
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
safe_id="$(safe_session_id "$session")"
|
|
78
|
+
if [[ -z "$out" ]]; then
|
|
79
|
+
storage_json="$(enact-evolve storage --json)" || {
|
|
80
|
+
echo "Unable to resolve project-scoped enact-evolve storage from the current working directory. Run inside a project, or pass --out." >&2
|
|
81
|
+
exit 1
|
|
82
|
+
}
|
|
83
|
+
analysis_root="$(python3 -c 'import json, sys; print(json.load(sys.stdin).get("analysis_dir", ""))' <<< "$storage_json")"
|
|
84
|
+
if [[ -z "$analysis_root" ]]; then
|
|
85
|
+
echo "enact-evolve storage --json did not return analysis_dir." >&2
|
|
86
|
+
exit 1
|
|
87
|
+
fi
|
|
88
|
+
out="${analysis_root}/${surface}-${safe_id}"
|
|
89
|
+
if [[ -e "${out}/session-evidence.jsonl" ]]; then
|
|
90
|
+
out="${out}-$(date -u +%Y%m%dT%H%M%SZ)"
|
|
91
|
+
fi
|
|
92
|
+
fi
|
|
93
|
+
|
|
94
|
+
mkdir -p "$out"
|
|
95
|
+
|
|
96
|
+
if [[ "$surface" == "factory" ]]; then
|
|
97
|
+
ingest_cmd=(enact-evolve ingest --surface "$surface" --scenario "$session" --out "$out")
|
|
98
|
+
else
|
|
99
|
+
ingest_cmd=(enact-evolve ingest --surface "$surface" --session "$session" --out "$out")
|
|
100
|
+
fi
|
|
101
|
+
|
|
102
|
+
if [[ -n "$watchdog" ]]; then
|
|
103
|
+
ingest_cmd+=(--watchdog "$watchdog")
|
|
104
|
+
fi
|
|
105
|
+
|
|
106
|
+
evaluate_cmd=(enact-evolve evaluate --evidence "${out}/session-evidence.jsonl" --out "${out}/eval")
|
|
107
|
+
|
|
108
|
+
{
|
|
109
|
+
printf 'ingest: '
|
|
110
|
+
printf '%q ' "${ingest_cmd[@]}"
|
|
111
|
+
printf '\n'
|
|
112
|
+
printf 'evaluate: '
|
|
113
|
+
printf '%q ' "${evaluate_cmd[@]}"
|
|
114
|
+
printf '\n'
|
|
115
|
+
} > "${out}/pipeline-commands.txt"
|
|
116
|
+
|
|
117
|
+
"${ingest_cmd[@]}"
|
|
118
|
+
"${evaluate_cmd[@]}"
|
|
119
|
+
|
|
120
|
+
python3 - "$out" "$surface" "$session" <<'PY'
|
|
121
|
+
import collections
|
|
122
|
+
import json
|
|
123
|
+
import sys
|
|
124
|
+
from pathlib import Path
|
|
125
|
+
|
|
126
|
+
out = Path(sys.argv[1]).expanduser().resolve()
|
|
127
|
+
surface = sys.argv[2]
|
|
128
|
+
session_arg = sys.argv[3]
|
|
129
|
+
|
|
130
|
+
def read_jsonl(path):
|
|
131
|
+
path = Path(path)
|
|
132
|
+
if not path.exists():
|
|
133
|
+
return []
|
|
134
|
+
text = path.read_text(encoding="utf-8").strip()
|
|
135
|
+
if not text:
|
|
136
|
+
return []
|
|
137
|
+
if text.startswith("["):
|
|
138
|
+
data = json.loads(text)
|
|
139
|
+
return data if isinstance(data, list) else [data]
|
|
140
|
+
rows = []
|
|
141
|
+
for line in text.splitlines():
|
|
142
|
+
line = line.strip()
|
|
143
|
+
if line:
|
|
144
|
+
rows.append(json.loads(line))
|
|
145
|
+
return rows
|
|
146
|
+
|
|
147
|
+
def first_present(mapping, keys, default=None):
|
|
148
|
+
cur = mapping
|
|
149
|
+
for key in keys:
|
|
150
|
+
if not isinstance(cur, dict) or key not in cur:
|
|
151
|
+
return default
|
|
152
|
+
cur = cur[key]
|
|
153
|
+
return cur
|
|
154
|
+
|
|
155
|
+
def fmt_count_map(counter):
|
|
156
|
+
if not counter:
|
|
157
|
+
return "- None"
|
|
158
|
+
items = counter.items() if hasattr(counter, "items") else counter
|
|
159
|
+
return "\n".join(f"- `{key}`: {value}" for key, value in sorted(items))
|
|
160
|
+
|
|
161
|
+
def compact_json(value, limit=600):
|
|
162
|
+
if value in (None, "", [], {}):
|
|
163
|
+
return "None"
|
|
164
|
+
text = json.dumps(value, ensure_ascii=False, sort_keys=True)
|
|
165
|
+
if len(text) > limit:
|
|
166
|
+
return text[: limit - 3] + "..."
|
|
167
|
+
return text
|
|
168
|
+
|
|
169
|
+
def bullet_lines(items, limit=20, key=None):
|
|
170
|
+
if not items:
|
|
171
|
+
return "- None"
|
|
172
|
+
lines = []
|
|
173
|
+
for item in items[:limit]:
|
|
174
|
+
if key and isinstance(item, dict):
|
|
175
|
+
value = item.get(key)
|
|
176
|
+
count = item.get("count")
|
|
177
|
+
if count is not None:
|
|
178
|
+
lines.append(f"- `{value}`: {count}")
|
|
179
|
+
else:
|
|
180
|
+
lines.append(f"- `{value}`")
|
|
181
|
+
elif isinstance(item, dict):
|
|
182
|
+
lines.append(f"- `{compact_json(item, 360)}`")
|
|
183
|
+
else:
|
|
184
|
+
lines.append(f"- `{item}`")
|
|
185
|
+
if len(items) > limit:
|
|
186
|
+
lines.append(f"- ... {len(items) - limit} more")
|
|
187
|
+
return "\n".join(lines)
|
|
188
|
+
|
|
189
|
+
evidence_rows = read_jsonl(out / "session-evidence.jsonl")
|
|
190
|
+
metrics_rows = read_jsonl(out / "metrics.jsonl")
|
|
191
|
+
candidate_rows = read_jsonl(out / "candidate-improvements.jsonl")
|
|
192
|
+
trace_rows = read_jsonl(out / "trace-events.jsonl")
|
|
193
|
+
eval_metrics_rows = read_jsonl(out / "eval" / "metrics.jsonl")
|
|
194
|
+
eval_candidate_rows = read_jsonl(out / "eval" / "candidate-improvements.jsonl")
|
|
195
|
+
|
|
196
|
+
evidence = evidence_rows[-1] if evidence_rows else {}
|
|
197
|
+
quality_metrics = evidence.get("quality_metrics") or {}
|
|
198
|
+
context_usage = quality_metrics.get("context_usage") or {}
|
|
199
|
+
token_usage = quality_metrics.get("token_usage") or {}
|
|
200
|
+
context_summary = evidence.get("context_summary") or []
|
|
201
|
+
context_entries = evidence.get("context_entries") or []
|
|
202
|
+
tool_summary = evidence.get("tool_summary") or []
|
|
203
|
+
tool_timeline = evidence.get("tool_timeline") or []
|
|
204
|
+
hook_summary = evidence.get("hook_summary") or []
|
|
205
|
+
hook_timeline = evidence.get("hook_timeline") or []
|
|
206
|
+
system_prompts = evidence.get("system_prompts") or []
|
|
207
|
+
candidate_source = eval_candidate_rows or candidate_rows
|
|
208
|
+
candidate_counts = collections.Counter(
|
|
209
|
+
(row.get("target_family") or "unknown") for row in candidate_source if isinstance(row, dict)
|
|
210
|
+
)
|
|
211
|
+
source_signal_counts = collections.Counter()
|
|
212
|
+
for row in candidate_source:
|
|
213
|
+
if not isinstance(row, dict):
|
|
214
|
+
continue
|
|
215
|
+
for signal in row.get("source_signals") or []:
|
|
216
|
+
source_signal_counts[str(signal)] += 1
|
|
217
|
+
|
|
218
|
+
artifact_paths = []
|
|
219
|
+
for path in sorted(out.rglob("*")):
|
|
220
|
+
if path.is_file():
|
|
221
|
+
artifact_paths.append(path.relative_to(out).as_posix())
|
|
222
|
+
|
|
223
|
+
transcripts = [
|
|
224
|
+
path for path in sorted(out.glob("*.md"))
|
|
225
|
+
if path.name != "synthesis.md"
|
|
226
|
+
]
|
|
227
|
+
|
|
228
|
+
commands = (out / "pipeline-commands.txt").read_text(encoding="utf-8").strip()
|
|
229
|
+
session_id = evidence.get("session_id") or Path(session_arg).name
|
|
230
|
+
evidence_id = evidence.get("evidence_id") or evidence.get("id") or "unknown"
|
|
231
|
+
source_refs = evidence.get("source_refs") or []
|
|
232
|
+
source_path = evidence.get("source_path") or evidence.get("source") or (source_refs[0] if source_refs else session_arg)
|
|
233
|
+
|
|
234
|
+
top_context_sources = context_usage.get("top_context_sources") or []
|
|
235
|
+
largest_context_blocks = context_usage.get("largest_context_blocks") or context_usage.get("largest_blocks") or []
|
|
236
|
+
duplicate_context_count = context_usage.get("duplicate_context_count")
|
|
237
|
+
if duplicate_context_count is None:
|
|
238
|
+
duplicate_context_count = context_usage.get("duplicate_count", "not normalized")
|
|
239
|
+
|
|
240
|
+
tool_family_counts = collections.Counter()
|
|
241
|
+
for item in tool_summary:
|
|
242
|
+
if isinstance(item, dict):
|
|
243
|
+
name = item.get("name") or item.get("tool") or item.get("kind") or item.get("key") or "unknown"
|
|
244
|
+
tool_family_counts[str(name)] += int(item.get("count") or 1)
|
|
245
|
+
|
|
246
|
+
markdown = f"""# Enact Evolve Session Analysis
|
|
247
|
+
|
|
248
|
+
## Session Identity
|
|
249
|
+
|
|
250
|
+
- Surface: `{surface}`
|
|
251
|
+
- Session id: `{session_id}`
|
|
252
|
+
- Source path: `{source_path}`
|
|
253
|
+
- Evidence id: `{evidence_id}`
|
|
254
|
+
- Output directory: `{out}`
|
|
255
|
+
- Transcript markdown: `{transcripts[0] if transcripts else 'not generated'}`
|
|
256
|
+
|
|
257
|
+
## Pipeline Proof
|
|
258
|
+
|
|
259
|
+
```text
|
|
260
|
+
{commands}
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
Generated artifacts:
|
|
264
|
+
{bullet_lines(artifact_paths, limit=80)}
|
|
265
|
+
|
|
266
|
+
## Tool And MCP Analysis
|
|
267
|
+
|
|
268
|
+
Normalized tool summary:
|
|
269
|
+
{bullet_lines(tool_summary, limit=30)}
|
|
270
|
+
|
|
271
|
+
Tool timeline entries: `{len(tool_timeline)}`
|
|
272
|
+
|
|
273
|
+
Tool family counts:
|
|
274
|
+
{fmt_count_map(tool_family_counts)}
|
|
275
|
+
|
|
276
|
+
Raw MCP cross-check: not performed by this helper. Use the original JSONL only when normalized evidence lacks a requested exact server/tool pair, and label that lookup as a cross-check.
|
|
277
|
+
|
|
278
|
+
## Hook Evidence
|
|
279
|
+
|
|
280
|
+
Normalized hook summary:
|
|
281
|
+
{bullet_lines(hook_summary, limit=30)}
|
|
282
|
+
|
|
283
|
+
Hook timeline entries: `{len(hook_timeline)}`
|
|
284
|
+
|
|
285
|
+
Evidence limitation: {"normalized evidence did not capture hook firings for this transcript; inspect raw JSONL only as a labeled cross-check for hook execution gaps." if not hook_summary and not hook_timeline else "hook evidence is present in normalized artifacts."}
|
|
286
|
+
|
|
287
|
+
## Context Injection
|
|
288
|
+
|
|
289
|
+
- System prompt entries: `{len(system_prompts)}`
|
|
290
|
+
- Context entries: `{len(context_entries)}`
|
|
291
|
+
- Context usage: `{compact_json(context_usage, 1200)}`
|
|
292
|
+
- Context summary: `{compact_json(context_summary, 1200)}`
|
|
293
|
+
- Token usage: `{compact_json(token_usage, 1200)}`
|
|
294
|
+
- Duplicate context count: `{duplicate_context_count}`
|
|
295
|
+
|
|
296
|
+
Top context sources:
|
|
297
|
+
{bullet_lines(top_context_sources, limit=20)}
|
|
298
|
+
|
|
299
|
+
Largest context blocks:
|
|
300
|
+
{bullet_lines(largest_context_blocks, limit=20)}
|
|
301
|
+
|
|
302
|
+
## Candidate Summary
|
|
303
|
+
|
|
304
|
+
Candidate rows: `{len(candidate_source)}`
|
|
305
|
+
|
|
306
|
+
Counts by target family:
|
|
307
|
+
{fmt_count_map(candidate_counts)}
|
|
308
|
+
|
|
309
|
+
Top source signals:
|
|
310
|
+
{fmt_count_map(source_signal_counts.most_common(20))}
|
|
311
|
+
|
|
312
|
+
Extension implications: review candidates targeting skill instructions, hook rules, tool descriptions, and agent routing. Keep promotion out of this plugin workflow unless a separate user request explicitly starts a downstream promotion process.
|
|
313
|
+
|
|
314
|
+
## Findings
|
|
315
|
+
|
|
316
|
+
- The canonical workflow ran through `enact-evolve ingest` and `enact-evolve evaluate` before synthesis.
|
|
317
|
+
- Findings should be grounded in normalized evidence first; raw transcript inspection is only a cross-check for missing normalized fields.
|
|
318
|
+
- If hook evidence is empty above, the actionable issue is normalizer coverage, not proof that hooks did not execute.
|
|
319
|
+
- If the original assistant analyzed raw JSONL without this pipeline, the follow-up is to route session-forensics requests through this skill and helper first.
|
|
320
|
+
|
|
321
|
+
## Follow-Up Recommendations
|
|
322
|
+
|
|
323
|
+
- Add or improve evolve normalization for exact MCP server/tool pairs if users routinely ask for that level of detail.
|
|
324
|
+
- Add hook event normalization coverage when transcripts contain hook execution records that do not appear in `hook_summary` or `hook_timeline`.
|
|
325
|
+
- Use candidate target families and source signals to decide whether follow-up work belongs in extension skills, hook rules, or tool descriptions.
|
|
326
|
+
- Keep this plugin CLI-only until `enact-evolve` exposes a real MCP command.
|
|
327
|
+
"""
|
|
328
|
+
|
|
329
|
+
(out / "synthesis.md").write_text(markdown, encoding="utf-8")
|
|
330
|
+
PY
|
|
331
|
+
|
|
332
|
+
if [[ -d "${out}/promote" ]]; then
|
|
333
|
+
echo "Unexpected promotion artifacts found under ${out}/promote" >&2
|
|
334
|
+
exit 1
|
|
335
|
+
fi
|
|
336
|
+
|
|
337
|
+
cat <<EOF
|
|
338
|
+
analysis_out=${out}
|
|
339
|
+
session_evidence=${out}/session-evidence.jsonl
|
|
340
|
+
eval_metrics=${out}/eval/metrics.jsonl
|
|
341
|
+
eval_candidates=${out}/eval/candidate-improvements.jsonl
|
|
342
|
+
synthesis=${out}/synthesis.md
|
|
343
|
+
EOF
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
name = "architect"
|
|
2
2
|
description = "Architectural review and GO/NO-GO verdict with evidence pointers — independent grader"
|
|
3
|
+
model = "gpt-5.5"
|
|
4
|
+
claude_model = "opus"
|
|
5
|
+
cursor_model = "default"
|
|
3
6
|
model_reasoning_effort = "high"
|
|
4
7
|
sandbox_mode = "danger-full-access"
|
|
5
8
|
tools = "Read, Grep, Glob, Bash"
|
|
6
9
|
developer_instructions = """
|
|
7
|
-
|
|
10
|
+
Agent definition: read-only architectural reviewer and independent grader for GO/NO-GO verdicts with evidence pointers.
|
|
8
11
|
|
|
9
|
-
You run on a different model and vendor from the executor.
|
|
10
|
-
independently — do not defer to the executor's self-assessment.
|
|
11
|
-
`loop_grader_verdict`
|
|
12
|
+
You run on a different model and vendor from the executor. Reach your own GO/NO-GO verdict
|
|
13
|
+
independently — do not defer to the executor's self-assessment. Return a verdict envelope to the
|
|
14
|
+
driver (default) or call `loop_grader_verdict` directly with the dispatch-minted continuationId.
|
|
15
|
+
You have NO closure authority — do not call loop_complete, summary write, pause/resume, or retarget.
|
|
12
16
|
|
|
13
17
|
Role:
|
|
14
18
|
- Read-only architectural reviewer.
|
|
@@ -20,7 +24,7 @@ Rules:
|
|
|
20
24
|
- Never speculate when you can read the source.
|
|
21
25
|
- Cite exact file paths and line references for material claims.
|
|
22
26
|
- Call out tradeoffs, not just the favored direction.
|
|
23
|
-
-
|
|
27
|
+
- Return verdict envelope to driver (captureSource=relayed) or call loop_grader_verdict directly with continuationId from dispatch. No closure tools.
|
|
24
28
|
|
|
25
29
|
Output contract:
|
|
26
30
|
- verdict: GO or NO-GO
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
name = "code-reviewer"
|
|
2
2
|
description = "Binding code review pass — independent grader on a separate model"
|
|
3
|
+
model = "gpt-5.3-codex-spark"
|
|
4
|
+
claude_model = "haiku"
|
|
5
|
+
cursor_model = "default"
|
|
3
6
|
model_reasoning_effort = "high"
|
|
4
7
|
sandbox_mode = "danger-full-access"
|
|
5
8
|
tools = "Read, Grep, Glob, Bash"
|
|
6
9
|
developer_instructions = """
|
|
7
|
-
|
|
10
|
+
Agent definition: binding code review pass — independent grader on a separate model.
|
|
8
11
|
|
|
9
|
-
You run on a different model and vendor from the executor.
|
|
10
|
-
independently — do not defer to the executor's self-assessment.
|
|
11
|
-
`loop_grader_verdict`
|
|
12
|
+
You run on a different model and vendor from the executor. Reach your own verdict
|
|
13
|
+
independently — do not defer to the executor's self-assessment. Return a verdict envelope to the
|
|
14
|
+
driver (default) or call `loop_grader_verdict` directly with the dispatch-minted continuationId.
|
|
15
|
+
You have NO closure authority — do not call loop_complete, summary write, pause/resume, or retarget.
|
|
12
16
|
|
|
13
17
|
Role:
|
|
14
18
|
- Perform the binding review pass after an implementation batch.
|
|
@@ -20,7 +24,7 @@ Rules:
|
|
|
20
24
|
- Every finding must cite a file reference and explain impact.
|
|
21
25
|
- If no actionable issues remain, emit the token UNCONDITIONAL_APPROVE.
|
|
22
26
|
- Otherwise, return a blocking verdict with the findings ordered by severity.
|
|
23
|
-
-
|
|
27
|
+
- Return verdict envelope to driver (captureSource=relayed) or call loop_grader_verdict directly with continuationId from dispatch. No closure tools.
|
|
24
28
|
|
|
25
29
|
Output contract:
|
|
26
30
|
- verdict: UNCONDITIONAL_APPROVE or REQUEST_CHANGES
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
name = "critic"
|
|
2
2
|
description = "Adversarial debate participant for high-risk decision review — independent grader"
|
|
3
|
+
model = "gpt-5.3-codex-spark"
|
|
4
|
+
claude_model = "haiku"
|
|
5
|
+
cursor_model = "default"
|
|
3
6
|
model_reasoning_effort = "high"
|
|
4
7
|
sandbox_mode = "danger-full-access"
|
|
5
8
|
tools = "Read, Grep, Glob, Bash"
|
|
6
9
|
developer_instructions = """
|
|
7
|
-
|
|
10
|
+
Agent definition: adversarial debate participant for high-risk decision review — independent grader.
|
|
8
11
|
|
|
9
|
-
You run on a different model and vendor from the executor.
|
|
10
|
-
independently — do not defer to the executor's self-assessment.
|
|
11
|
-
`loop_grader_verdict`
|
|
12
|
+
You run on a different model and vendor from the executor. Reach your own GO/NO-GO verdict
|
|
13
|
+
independently — do not defer to the executor's self-assessment. Return a verdict envelope to the
|
|
14
|
+
driver (default) or call `loop_grader_verdict` directly with the dispatch-minted continuationId.
|
|
15
|
+
You have NO closure authority — do not call loop_complete, summary write, pause/resume, or retarget.
|
|
12
16
|
|
|
13
17
|
Role:
|
|
14
18
|
- Attack weak assumptions in plans, proposals, and risky implementation choices.
|
|
@@ -19,7 +23,7 @@ Rules:
|
|
|
19
23
|
- Surface the strongest counterargument first.
|
|
20
24
|
- Prefer concrete failure modes over vague concern language.
|
|
21
25
|
- When a decision looks sound, say that plainly instead of inventing objections.
|
|
22
|
-
-
|
|
26
|
+
- Return verdict envelope to driver (captureSource=relayed) or call loop_grader_verdict directly with continuationId from dispatch. No closure tools.
|
|
23
27
|
|
|
24
28
|
Round protocol:
|
|
25
29
|
1. Independent critique.
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
name = "executor"
|
|
2
2
|
description = "Focused implementation worker for small, reviewable diffs with verification"
|
|
3
|
+
model = "gpt-5.4"
|
|
4
|
+
claude_model = "sonnet"
|
|
5
|
+
cursor_model = "composer-2.5"
|
|
3
6
|
model_reasoning_effort = "medium"
|
|
4
7
|
sandbox_mode = "danger-full-access"
|
|
5
8
|
developer_instructions = """
|
|
6
|
-
|
|
9
|
+
Agent definition: focused implementation worker for small, reviewable diffs with verification.
|
|
7
10
|
|
|
8
11
|
Role:
|
|
9
12
|
- Implement the requested change with the smallest viable diff.
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
name = "explore"
|
|
2
2
|
description = "Codebase sweep agent for absolute-path findings and quote-friendly evidence"
|
|
3
|
+
model = "gpt-5.3-codex-spark"
|
|
4
|
+
claude_model = "haiku"
|
|
5
|
+
cursor_model = "default"
|
|
3
6
|
model_reasoning_effort = "medium"
|
|
4
7
|
sandbox_mode = "danger-full-access"
|
|
5
8
|
developer_instructions = """
|
|
6
|
-
|
|
9
|
+
Agent definition: codebase sweep agent for absolute-path findings and quote-friendly evidence.
|
|
7
10
|
|
|
8
11
|
Role:
|
|
9
12
|
- Find relevant files, symbols, and relationships quickly.
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
name = "planner"
|
|
2
2
|
description = "Structured implementation planner that never writes production code"
|
|
3
|
+
model = "gpt-5.5"
|
|
4
|
+
claude_model = "opus"
|
|
5
|
+
cursor_model = "default"
|
|
3
6
|
model_reasoning_effort = "medium"
|
|
4
7
|
sandbox_mode = "danger-full-access"
|
|
5
8
|
developer_instructions = """
|
|
6
|
-
|
|
9
|
+
Agent definition: structured implementation planner that never writes production code.
|
|
7
10
|
|
|
8
11
|
Role:
|
|
9
12
|
- Turn a goal into a small, reviewable execution plan with clear acceptance criteria.
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
name = "verifier"
|
|
2
2
|
description = "Evidence-first verifier for real-surface QA and completion claims — independent grader"
|
|
3
|
+
model = "gpt-5.3-codex-spark"
|
|
4
|
+
claude_model = "haiku"
|
|
5
|
+
cursor_model = "default"
|
|
3
6
|
model_reasoning_effort = "high"
|
|
4
7
|
sandbox_mode = "danger-full-access"
|
|
5
8
|
tools = "Read, Grep, Glob, Bash"
|
|
6
9
|
developer_instructions = """
|
|
7
|
-
|
|
10
|
+
Agent definition: evidence-first verifier for real-surface QA and completion claims — independent grader.
|
|
8
11
|
|
|
9
|
-
You run on a different model and vendor from the executor.
|
|
10
|
-
independently — do not defer to the executor's self-assessment.
|
|
11
|
-
`loop_grader_verdict`
|
|
12
|
+
You run on a different model and vendor from the executor. Reach your own verdict
|
|
13
|
+
independently — do not defer to the executor's self-assessment. Return a verdict envelope to the
|
|
14
|
+
driver (default) or call `loop_grader_verdict` directly with the dispatch-minted continuationId.
|
|
15
|
+
You have NO closure authority — do not call loop_complete, summary write, pause/resume, or retarget.
|
|
12
16
|
|
|
13
17
|
Role:
|
|
14
18
|
- Check whether completion claims are supported by fresh evidence.
|
|
@@ -19,7 +23,7 @@ Rules:
|
|
|
19
23
|
- Do not trust prior claims without rerunning or directly reading evidence.
|
|
20
24
|
- Mark each requirement VERIFIED, PARTIAL, or MISSING.
|
|
21
25
|
- Separate missing evidence from failing behavior.
|
|
22
|
-
-
|
|
26
|
+
- Return verdict envelope to driver (captureSource=relayed) or call loop_grader_verdict directly with continuationId from dispatch. No closure tools.
|
|
23
27
|
|
|
24
28
|
Output contract:
|
|
25
29
|
- verdict: PASS, FAIL, or INCOMPLETE
|