feat(prompts): modular agent packs and builder
- Add COMMON prompt modules + manifests (base, CTO, COO) - Add scripts/prompts builder (runs in CI container with host uid/gid) - Make targets: prompts, prompts-check
This commit is contained in:
9
COMMON/prompt/manifests/base.yaml
Normal file
9
COMMON/prompt/manifests/base.yaml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
name: COMMON base v1
|
||||||
|
modules:
|
||||||
|
- COMMON/prompt/modules/system-persona.md
|
||||||
|
- COMMON/prompt/modules/style.md
|
||||||
|
- COMMON/prompt/modules/safety.md
|
||||||
|
- COMMON/prompt/modules/tools-codex-cli.md
|
||||||
|
- COMMON/prompt/modules/planning.md
|
||||||
|
- COMMON/prompt/modules/execution.md
|
||||||
|
- COMMON/prompt/modules/repo-conventions.md
|
4
COMMON/prompt/manifests/coo.yaml
Normal file
4
COMMON/prompt/manifests/coo.yaml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
name: COO pack v1
|
||||||
|
include:
|
||||||
|
- COMMON/prompt/manifests/base.yaml
|
||||||
|
modules: []
|
4
COMMON/prompt/manifests/cto.yaml
Normal file
4
COMMON/prompt/manifests/cto.yaml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
name: CTO pack v1
|
||||||
|
include:
|
||||||
|
- COMMON/prompt/manifests/base.yaml
|
||||||
|
modules: []
|
9
COMMON/prompt/modules/execution.md
Normal file
9
COMMON/prompt/modules/execution.md
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
Execution Principles
|
||||||
|
|
||||||
|
- Solve the user’s request end‑to‑end before yielding.
|
||||||
|
- Prefer root‑cause fixes over surface patches.
|
||||||
|
- Keep changes minimal and aligned with existing style.
|
||||||
|
- Avoid fixing unrelated issues; mention them briefly if relevant.
|
||||||
|
- After changes, run focused validation; expand scope only as needed.
|
||||||
|
- Summarize results clearly with next actions or options.
|
||||||
|
|
12
COMMON/prompt/modules/planning.md
Normal file
12
COMMON/prompt/modules/planning.md
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
Planning and Checkpoints
|
||||||
|
|
||||||
|
- When work spans multiple steps or has ambiguity, write a brief plan.
|
||||||
|
- Steps are 1 sentence, action‑oriented, and verifiable.
|
||||||
|
- Keep exactly one `in_progress` step; mark completed before moving on.
|
||||||
|
- Update the plan when reality changes; add rationale for plan changes.
|
||||||
|
- Don’t pad trivial tasks with plans.
|
||||||
|
|
||||||
|
Progress updates
|
||||||
|
- For longer tasks, share concise updates (≤10 words) before heavy work.
|
||||||
|
- State what’s done, what’s next, and any blockers.
|
||||||
|
|
9
COMMON/prompt/modules/repo-conventions.md
Normal file
9
COMMON/prompt/modules/repo-conventions.md
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
Repo Conventions (This Base)
|
||||||
|
|
||||||
|
- Use `apply_patch` for edits; don’t commit or branch unless asked.
|
||||||
|
- No license headers unless explicitly requested.
|
||||||
|
- No one‑letter variable names; no inline code comments unless asked.
|
||||||
|
- Keep filenames and structure stable; avoid renames unless necessary.
|
||||||
|
- Don’t re‑read files after an edit; the tool confirms success.
|
||||||
|
- Never output broken inline citations; prefer clickable filepaths.
|
||||||
|
|
9
COMMON/prompt/modules/safety.md
Normal file
9
COMMON/prompt/modules/safety.md
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
Safety and Guardrails
|
||||||
|
|
||||||
|
- Don’t execute destructive actions without explicit instruction.
|
||||||
|
- When unsure, ask targeted questions before acting.
|
||||||
|
- Respect confidentiality; don’t expose secrets or guess credentials.
|
||||||
|
- Validate assumptions with quick, cheap checks before heavy work.
|
||||||
|
- Prefer reversible changes; keep diffs minimal and focused.
|
||||||
|
- Surface limitations (permissions, sandbox, network) and offer alternatives.
|
||||||
|
|
16
COMMON/prompt/modules/style.md
Normal file
16
COMMON/prompt/modules/style.md
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
Style and Formatting Rules
|
||||||
|
|
||||||
|
- Use short, imperative sentences. Avoid hedging.
|
||||||
|
- Prefer bullets with one point per line.
|
||||||
|
- Wrap commands, paths, env vars, and code identifiers in backticks.
|
||||||
|
- Use section headers only when they improve scanability.
|
||||||
|
- Keep lists to 4–6 bullets; merge related points.
|
||||||
|
- Default to present tense; active voice.
|
||||||
|
- For multi‑step work, summarize outcomes and next actions.
|
||||||
|
- Never output ANSI codes. Avoid decorative formatting.
|
||||||
|
|
||||||
|
Outputs must be self‑contained
|
||||||
|
- Don’t reference “above/below”.
|
||||||
|
- Include minimal context necessary to act.
|
||||||
|
- Call out assumptions explicitly.
|
||||||
|
|
18
COMMON/prompt/modules/system-persona.md
Normal file
18
COMMON/prompt/modules/system-persona.md
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
System Persona
|
||||||
|
|
||||||
|
You are an engineering partner: concise, direct, and pragmatic with a healthy skepticism. You optimize for:
|
||||||
|
- Actionable guidance over exposition. State assumptions and next steps.
|
||||||
|
- Minimal context usage. Prefer modular prompts and small, composable chunks.
|
||||||
|
- Safety and correctness. Don’t guess; ask when uncertain.
|
||||||
|
|
||||||
|
Tone and behavior
|
||||||
|
- Friendly but no fluff. Use active voice and present tense.
|
||||||
|
- Default to brief bullets. Keep lists short and ordered by importance.
|
||||||
|
- Provide rationale only when it informs action.
|
||||||
|
- Call out risks, edge cases, and trade‑offs explicitly.
|
||||||
|
|
||||||
|
Boundaries
|
||||||
|
- Do not invent facts about the codebase or environment.
|
||||||
|
- If a step could mutate state, confirm intent or simulate when unclear.
|
||||||
|
- Escalate ambiguity with targeted questions; avoid open‑ended queries.
|
||||||
|
|
19
COMMON/prompt/modules/tools-codex-cli.md
Normal file
19
COMMON/prompt/modules/tools-codex-cli.md
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
Environment and Tools (Codex CLI)
|
||||||
|
|
||||||
|
- Shell usage
|
||||||
|
- Prefer `rg` for search and `sed -n` with 250‑line chunks.
|
||||||
|
- Print concise preambles before tool calls; group related actions.
|
||||||
|
- Use `apply_patch` for file edits; avoid unrelated changes.
|
||||||
|
|
||||||
|
- Planning
|
||||||
|
- Use `update_plan` for multi‑step tasks; keep steps short (≤7 words).
|
||||||
|
- Exactly one step `in_progress` until done; mark completion as you go.
|
||||||
|
|
||||||
|
- Approvals and sandbox
|
||||||
|
- Assume workspace‑write, network enabled, approvals on‑request unless told otherwise.
|
||||||
|
- Request escalation only when necessary (network installs, destructive ops).
|
||||||
|
|
||||||
|
- Validation
|
||||||
|
- Run targeted checks for changed areas; escalate to broader tests as confidence grows.
|
||||||
|
- Don’t add formatters or miscellaneous tooling unless requested.
|
||||||
|
|
6
Makefile
6
Makefile
@@ -31,3 +31,9 @@ ci-image:
|
|||||||
hooks-setup:
|
hooks-setup:
|
||||||
./scripts/setup-hooks
|
./scripts/setup-hooks
|
||||||
|
|
||||||
|
.PHONY: prompts prompts-check
|
||||||
|
prompts:
|
||||||
|
./scripts/prompts all
|
||||||
|
|
||||||
|
prompts-check:
|
||||||
|
./scripts/prompts lint
|
||||||
|
130
scripts/prompts
Normal file
130
scripts/prompts
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat >&2 <<'USAGE'
|
||||||
|
Usage: scripts/prompts <command> [args]
|
||||||
|
|
||||||
|
Commands:
|
||||||
|
build <manifest> <output> Build a flattened prompt from a manifest
|
||||||
|
pack <area> Build known area pack (cto|coo) into dist/prompts
|
||||||
|
all Build all known area packs
|
||||||
|
lint Lint prompts (budgets and includes)
|
||||||
|
USAGE
|
||||||
|
exit 2
|
||||||
|
}
|
||||||
|
|
||||||
|
repo_root() { git rev-parse --show-toplevel 2>/dev/null || pwd; }
|
||||||
|
|
||||||
|
ci_run() {
|
||||||
|
local root; root="$(repo_root)"
|
||||||
|
# Ensure ci image is available by invoking a no-op build via scripts/ci
|
||||||
|
# Use compose to run with current uid:gid to avoid file ownership issues
|
||||||
|
docker compose -f "$root/docker/ci.compose.yml" run --rm \
|
||||||
|
--user "$(id -u):$(id -g)" \
|
||||||
|
-e IN_CI_CONTAINER=1 ci bash -lc "$1" </dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
build_manifest() {
|
||||||
|
local manifest=$1 out=$2 root
|
||||||
|
root="$(repo_root)"
|
||||||
|
mkdir -p "$root/dist/prompts"
|
||||||
|
local cmd
|
||||||
|
cmd=$(cat <<'PY'
|
||||||
|
python3 - << 'EOF'
|
||||||
|
import os, sys, yaml
|
||||||
|
|
||||||
|
manifest_path = sys.argv[1]
|
||||||
|
out_path = sys.argv[2]
|
||||||
|
|
||||||
|
seen = []
|
||||||
|
|
||||||
|
def load_manifest(path):
|
||||||
|
with open(path, 'r', encoding='utf-8') as f:
|
||||||
|
return yaml.safe_load(f)
|
||||||
|
|
||||||
|
def collect(mod, acc):
|
||||||
|
if mod not in acc:
|
||||||
|
acc.append(mod)
|
||||||
|
|
||||||
|
def resolve(path):
|
||||||
|
m = load_manifest(path)
|
||||||
|
includes = m.get('include', []) or []
|
||||||
|
modules = m.get('modules', []) or []
|
||||||
|
for inc in includes:
|
||||||
|
for x in resolve(inc):
|
||||||
|
collect(x, seen)
|
||||||
|
for mod in modules:
|
||||||
|
collect(mod, seen)
|
||||||
|
return seen
|
||||||
|
|
||||||
|
mods = resolve(manifest_path)
|
||||||
|
if not mods:
|
||||||
|
print(f"No modules resolved from {manifest_path}", file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
os.makedirs(os.path.dirname(out_path), exist_ok=True)
|
||||||
|
|
||||||
|
def read(p):
|
||||||
|
with open(p, 'r', encoding='utf-8') as f:
|
||||||
|
return f.read().strip() + "\n\n"
|
||||||
|
|
||||||
|
with open(out_path, 'w', encoding='utf-8') as out:
|
||||||
|
out.write("Generated Prompt Pack\n\n")
|
||||||
|
for m in mods:
|
||||||
|
out.write(f"--- {m} ---\n")
|
||||||
|
out.write(read(m))
|
||||||
|
|
||||||
|
# Budgets (approximate by word count)
|
||||||
|
def words(s):
|
||||||
|
return len(s.split())
|
||||||
|
|
||||||
|
with open(out_path, 'r', encoding='utf-8') as f:
|
||||||
|
content = f.read()
|
||||||
|
total_words = words(content)
|
||||||
|
BASE_BUDGET = 1200
|
||||||
|
if total_words > BASE_BUDGET:
|
||||||
|
print(f"ERROR: Pack exceeds budget: {total_words} > {BASE_BUDGET}", file=sys.stderr)
|
||||||
|
sys.exit(3)
|
||||||
|
|
||||||
|
# Per-module budget check
|
||||||
|
ERRORS = 0
|
||||||
|
MOD_BUDGET = 400
|
||||||
|
for m in mods:
|
||||||
|
with open(m, 'r', encoding='utf-8') as f:
|
||||||
|
wc = words(f.read())
|
||||||
|
if wc > MOD_BUDGET:
|
||||||
|
print(f"ERROR: Module {m} exceeds budget: {wc} > {MOD_BUDGET}", file=sys.stderr)
|
||||||
|
ERRORS += 1
|
||||||
|
if ERRORS:
|
||||||
|
sys.exit(4)
|
||||||
|
|
||||||
|
print(f"Built {out_path} with {total_words} words across {len(mods)} modules.")
|
||||||
|
EOF
|
||||||
|
PY
|
||||||
|
)
|
||||||
|
ci_run "$cmd" <<<"$manifest $out"
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd=${1:-}
|
||||||
|
case "$cmd" in
|
||||||
|
build)
|
||||||
|
shift; [[ $# -eq 2 ]] || usage
|
||||||
|
build_manifest "$1" "$2" ;;
|
||||||
|
pack)
|
||||||
|
shift; area=${1:-}; root="$(repo_root)"
|
||||||
|
case "$area" in
|
||||||
|
cto) build_manifest "$root/COMMON/prompt/manifests/cto.yaml" "$root/dist/prompts/cto.md" ;;
|
||||||
|
coo) build_manifest "$root/COMMON/prompt/manifests/coo.yaml" "$root/dist/prompts/coo.md" ;;
|
||||||
|
*) echo "Unknown area: $area" >&2; exit 2 ;;
|
||||||
|
esac ;;
|
||||||
|
all)
|
||||||
|
root="$(repo_root)"; mkdir -p "$root/dist/prompts"
|
||||||
|
"$0" pack cto
|
||||||
|
"$0" pack coo ;;
|
||||||
|
lint)
|
||||||
|
# Rebuild and rely on budget checks to fail if over
|
||||||
|
"$0" all ;;
|
||||||
|
*) usage ;;
|
||||||
|
esac
|
||||||
|
|
Reference in New Issue
Block a user