-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathscaffold_repo_eval.py
More file actions
145 lines (105 loc) · 3.48 KB
/
scaffold_repo_eval.py
File metadata and controls
145 lines (105 loc) · 3.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#!/usr/bin/env python3
from __future__ import annotations
import argparse
import json
from pathlib import Path
README_TEMPLATE = """# Repo Agent Eval Kit
This directory was scaffolded by the `harness-engineering` skill.
## What to do next
1. Replace placeholders in `manifest.json`.
2. Create 8 to 20 real tasks under `tasks/`.
3. For each task, keep `spec.md` visible and `reviewer-notes.md` private when scoring.
4. Reuse the same task set to compare harness changes over time.
## Suggested surfaces
- frontend
- backend
- tests
- migration
- review
## Scoring dimensions
- correctness
- completeness
- code quality
- verification quality
"""
SPEC_TEMPLATE = """# Task Spec
Describe the task without leaking the final implementation.
## User-visible goal
...
## Constraints
- ...
## Allowed commands
- ...
## Expected verification
- ...
"""
REVIEWER_TEMPLATE = """# Reviewer Notes
Keep this file out of the evaluated prompt.
## Ground truth
- ...
## Common failure modes
- ...
## Scoring notes
- correctness:
- completeness:
- code quality:
- verification quality:
"""
def build_manifest(repo_name: str) -> dict:
return {
"version": 1,
"repo_name": repo_name,
"owner": "replace-me",
"generated_by": "harness-engineering",
"scoring": {
"correctness": 0.4,
"completeness": 0.25,
"code_quality": 0.2,
"verification_quality": 0.15,
},
"tasks": [
{
"id": "example-task-001",
"title": "Replace with a real task title",
"surface": "frontend",
"difficulty": "medium",
"source_type": "pull_request",
"source_ref": "replace-with-link-or-id",
"prompt_file": "tasks/example-task-001/spec.md",
"verification": [
{
"type": "command",
"command": "replace-with-real-command"
}
],
"hidden_reference": "tasks/example-task-001/reviewer-notes.md",
}
],
}
def write_file(path: Path, content: str, force: bool) -> None:
if path.exists() and not force:
return
path.write_text(content, encoding="utf-8")
def main() -> int:
parser = argparse.ArgumentParser(description="Scaffold a repo-specific agent eval starter kit.")
parser.add_argument("output_dir", help="Directory to create or update.")
parser.add_argument("--repo-name", required=True, help="Repository name to place in the manifest.")
parser.add_argument("--force", action="store_true", help="Overwrite existing scaffold files.")
args = parser.parse_args()
out = Path(args.output_dir).resolve()
tasks_dir = out / "tasks" / "example-task-001"
tasks_dir.mkdir(parents=True, exist_ok=True)
manifest = build_manifest(args.repo_name)
manifest_path = out / "manifest.json"
readme_path = out / "README.md"
spec_path = tasks_dir / "spec.md"
reviewer_path = tasks_dir / "reviewer-notes.md"
if not manifest_path.exists() or args.force:
manifest_path.write_text(json.dumps(manifest, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
write_file(readme_path, README_TEMPLATE, args.force)
write_file(spec_path, SPEC_TEMPLATE, args.force)
write_file(reviewer_path, REVIEWER_TEMPLATE, args.force)
print(f"Scaffolded repo eval kit at {out}")
return 0
if __name__ == "__main__":
raise SystemExit(main())