ghostdrive1 commited on
Commit
116524e
·
verified ·
1 Parent(s): 74b880e

Upload folder using huggingface_hub

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .claude/commands/benchmark.md +61 -0
  2. .claude/commands/checkout-branch.md +64 -0
  3. .claude/commands/create-branch.md +39 -0
  4. .claude/commands/create-pr.md +56 -0
  5. .claude/commands/finalize.md +79 -0
  6. .claude/commands/list-branches.md +40 -0
  7. .claude/commands/release.md +75 -0
  8. .claude/commands/remove-branch.md +41 -0
  9. .claude/package.json +1 -0
  10. .claude/projects/-home-david-projects-Kayba-agentic-context-engine/memory/feedback_bedrock_only.md +11 -0
  11. .claude/settings.json +8 -0
  12. .claude/skills/kayba-pipeline/SKILL.md +145 -0
  13. .claude/skills/kayba-pipeline/stage-1-api-analysis/SKILL.md +84 -0
  14. .claude/skills/kayba-pipeline/stage-2-domain-context/SKILL.md +166 -0
  15. .claude/skills/kayba-pipeline/stage-3-metrics/SKILL.md +180 -0
  16. .claude/skills/kayba-pipeline/stage-4-rubric/SKILL.md +163 -0
  17. .claude/skills/kayba-pipeline/stage-5-action-plan/SKILL.md +201 -0
  18. .claude/skills/kayba-pipeline/stage-6-hitl/SKILL.md +258 -0
  19. .claude/skills/kayba-pipeline/stage-7-fixer/SKILL.md +191 -0
  20. .env.example +69 -0
  21. .gitattributes +4 -0
  22. .github/workflows/docs.yml +55 -0
  23. .github/workflows/publish.yml +290 -0
  24. .github/workflows/test.yml +47 -0
  25. .gitignore +124 -0
  26. .gitmodules +3 -0
  27. .pre-commit-config.yaml +20 -0
  28. .specify/memory/constitution.md +121 -0
  29. .specify/scripts/bash/check-prerequisites.sh +166 -0
  30. .specify/scripts/bash/common.sh +156 -0
  31. .specify/scripts/bash/create-new-feature.sh +297 -0
  32. .specify/scripts/bash/setup-plan.sh +61 -0
  33. .specify/scripts/bash/update-agent-context.sh +810 -0
  34. .specify/templates/agent-file-template.md +28 -0
  35. .specify/templates/checklist-template.md +40 -0
  36. .specify/templates/constitution-template.md +50 -0
  37. .specify/templates/plan-template.md +104 -0
  38. .specify/templates/spec-template.md +115 -0
  39. .specify/templates/tasks-template.md +251 -0
  40. AGENTS.md +98 -0
  41. CHANGELOG.md +445 -0
  42. CLAUDE.md +99 -0
  43. CONTRIBUTING.md +183 -0
  44. Dockerfile +11 -10
  45. LICENSE +201 -0
  46. README.md +224 -10
  47. ace.toml +2 -0
  48. ace/__init__.py +197 -0
  49. ace/cli/__init__.py +39 -0
  50. ace/cli/client.py +310 -0
.claude/commands/benchmark.md ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Run a TAU-bench evaluation end-to-end and present results.
2
+
3
+ **Syntax:** `/benchmark <config> [mode] [extra-args]`
4
+
5
+ **Arguments:**
6
+
7
+ - `config` (from $ARGUMENTS, first word) — profile name: `haiku`, `sonnet`, `gpt4.1-mini`, `gpt4.1`, `fast`, `default`
8
+ - `mode` (from $ARGUMENTS, second word, optional) — `baseline` (default), `compare`, or `ace-only`
9
+ - `extra-args` (from $ARGUMENTS, remaining words) — forwarded verbatim to the CLI
10
+
11
+ **Workflow:**
12
+
13
+ 1. **Parse arguments** from `$ARGUMENTS`:
14
+ - Split into: `config` (first word), `mode` (second word if it matches baseline/compare/ace-only, else default to baseline), and `extra-args` (the rest)
15
+
16
+ 2. **Build the command:**
17
+ ```
18
+ uv run python scripts/run_tau_benchmark.py --config <config> --save-detailed <mode-flag> <extra-args>
19
+ ```
20
+ Mode flags:
21
+ - `baseline` → `--skip-ace`
22
+ - `compare` → `--compare`
23
+ - `ace-only` → (no flag)
24
+
25
+ 3. **Show the command** to the user before running
26
+
27
+ 4. **Run the command** with a 10-minute timeout (TAU-bench runs are long)
28
+
29
+ 5. **Find the latest result**: list `tau_benchmark_results/` sorted by modification time, pick the newest `*_summary.json`
30
+
31
+ 6. **Read the summary JSON** and present results using this format:
32
+
33
+ For baseline runs:
34
+ ```
35
+ ## <Mode>: <Model Short Name> — <Domain> (test split, k=<k>)
36
+
37
+ | Setting | Value |
38
+ |---------|-------|
39
+ | Model | <exact model id> |
40
+ | User LLM | <user_llm> |
41
+ | Domain | <domain> |
42
+ | Split | <split> (<N> tasks) |
43
+ | Max steps | <max_steps> |
44
+ | Seed | <seed> |
45
+
46
+ | Metric | Score |
47
+ |--------|-------|
48
+ | pass^1 | XX.XX% |
49
+ | pass^2 | XX.XX% |
50
+ | ... | ... |
51
+ ```
52
+
53
+ For comparison runs, add Baseline / ACE / Delta columns.
54
+
55
+ **Examples:**
56
+ - `/benchmark haiku` → baseline haiku run
57
+ - `/benchmark haiku compare` → baseline vs ACE comparison
58
+ - `/benchmark fast` → quick smoke test (3 tasks, k=1)
59
+ - `/benchmark sonnet compare --domain retail` → sonnet comparison on retail
60
+
61
+ **Key fields** to always include in the results table: exact model ID, user LLM, domain, split + task count, skillbook status, and all pass^k metrics.
.claude/commands/checkout-branch.md ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Switch to an existing branch by checking out its worktree, or creating one if needed.
2
+
3
+ **Arguments:** $ARGUMENTS should be the branch name (full or partial match)
4
+
5
+ **Examples:**
6
+ - `/checkout-branch feature/john/add-caching` → switch to branch (create worktree if needed)
7
+ - `/checkout-branch add-caching` → partial match, resolve to full branch name
8
+ - `/checkout-branch fix` → if multiple matches, list them and ask to be specific
9
+
10
+ **Steps:**
11
+ 1. Parse branch name from arguments
12
+ 2. Fetch latest from remote: `git fetch --prune`
13
+ 3. Get all branches (local + remote): `git branch -a --format='%(refname:short)'`
14
+ 4. Resolve branch name:
15
+ - Exact match: use directly
16
+ - Partial match: find branches containing the search term
17
+ - No match: show error with similar branches (if any)
18
+ 5. Get worktree list: `git worktree list --porcelain`
19
+ 6. Check if resolved branch has an existing worktree
20
+ 7. If worktree exists:
21
+ - Show path and suggest `cd <path>`
22
+ 8. If no worktree:
23
+ - Construct worktree path: `../<sanitized-branch-name>` (replace all `/` with `-`)
24
+ - If remote-only branch (starts with `origin/`): `git worktree add <path> -b <local-name> <remote-name>`
25
+ - If local branch: `git worktree add <path> <branch>`
26
+ - Symlink `.env`: if `<main-worktree>/.env` exists (get main worktree from `git worktree list --porcelain | head -1`), run `ln -s <main-worktree>/.env <new-worktree>/.env`
27
+ - Show path and suggest `cd <path>`
28
+
29
+ **On success (worktree exists), output:**
30
+ ```
31
+ ✓ Branch already has worktree at: <worktree-path>
32
+
33
+ To switch to the worktree:
34
+ cd <worktree-path>
35
+ ```
36
+
37
+ **On success (worktree created from local branch), output:**
38
+ ```
39
+ ✓ Created worktree: <worktree-path>
40
+ ✓ Linked .env → <main-worktree>/.env
41
+
42
+ To switch to the worktree:
43
+ cd <worktree-path>
44
+ ```
45
+
46
+ **On success (worktree created from remote branch), output:**
47
+ ```
48
+ ✓ Created local branch: <branch-name> (tracking origin/<branch-name>)
49
+ ✓ Created worktree: <worktree-path>
50
+ ✓ Linked .env → <main-worktree>/.env
51
+
52
+ To switch to the worktree:
53
+ cd <worktree-path>
54
+ ```
55
+
56
+ **Error handling:**
57
+ - Branch not found: "Branch not found: <name>. Did you mean one of these?" (list similar branches)
58
+ - Multiple partial matches: "Multiple branches match '<term>':" (list matches, ask to be more specific)
59
+ - No branches at all: "No branches found matching '<term>'"
60
+
61
+ **Branch resolution priority:**
62
+ 1. Exact match on full branch name
63
+ 2. Exact match on last segment (e.g., "add-caching" matches "feature/john/add-caching")
64
+ 3. Partial substring match anywhere in branch name
.claude/commands/create-branch.md ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Create a new git branch with an associated worktree following the project naming convention.
2
+
3
+ **Format:** `<type>/<developer>/<description>`
4
+ **Worktree:** `../<sanitized-branch-name>` (sibling to current worktree)
5
+
6
+ **Arguments:** $ARGUMENTS should be in format: `<type> <description>`
7
+
8
+ **Examples:**
9
+ - `/create-branch feature add-caching` → branch: `feature/<dev>/add-caching`, worktree: `../feature-<dev>-add-caching`
10
+ - `/create-branch fix login-error` → branch: `fix/<dev>/login-error`, worktree: `../fix-<dev>-login-error`
11
+
12
+ **Steps:**
13
+ 1. Parse type and description from arguments (validate type is one of: feature, fix, docs, refactor, test, chore)
14
+ 2. Get developer name from `git config user.name` (sanitize: lowercase, replace spaces with hyphens)
15
+ 3. Construct branch name: `<type>/<developer>/<description>`
16
+ 4. Construct worktree path: `../<type>-<developer>-<description>` (replace all `/` with `-`)
17
+ 5. Create branch and worktree atomically: `git worktree add -b <branch> <worktree-path>`
18
+ 6. Symlink `.env` from the main worktree into the new worktree:
19
+ - Get the main worktree path: `git worktree list --porcelain | head -1` (first `worktree` line)
20
+ - If `<main-worktree>/.env` exists, create symlink: `ln -s <main-worktree>/.env <new-worktree>/.env`
21
+ - If `.env` doesn't exist in main worktree, skip silently
22
+ 7. Report success with the created branch name and worktree path
23
+
24
+ **Valid types:** feature, fix, docs, refactor, test, chore
25
+
26
+ **On success, output:**
27
+ ```
28
+ ✓ Created branch: <branch-name>
29
+ ✓ Created worktree: <worktree-path>
30
+ ✓ Linked .env → <main-worktree>/.env
31
+
32
+ To switch to the new worktree:
33
+ cd <worktree-path>
34
+ ```
35
+
36
+ **Error handling:**
37
+ - If type is invalid, show valid types and abort
38
+ - If branch already exists, suggest checking it out instead
39
+ - If worktree path exists, suggest using existing worktree
.claude/commands/create-pr.md ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Create a pull request for the current branch against main.
2
+
3
+ **Arguments:** $ARGUMENTS (optional) — base branch override (defaults to `main`)
4
+
5
+ **Steps:**
6
+
7
+ 1. **Validate branch state:**
8
+ - Get current branch: `git branch --show-current`
9
+ - If on `main`, abort with error: "You're on main. Switch to a feature branch first."
10
+ - Determine base branch: use $ARGUMENTS if provided, otherwise `main`
11
+
12
+ 2. **Check for unmerged commits:**
13
+ - Run `git log <base>..HEAD --oneline`
14
+ - If no commits, abort: "No unmerged commits against <base>. Nothing to PR."
15
+
16
+ 3. **Gather context (run in parallel):**
17
+ - `git diff <base>...HEAD --stat` — file change summary
18
+ - `git log <base>..HEAD --format='%h %s'` — commit list
19
+ - `git diff <base>...HEAD` — full diff for understanding changes
20
+
21
+ 4. **Draft PR title and body:**
22
+ - Analyze the commits and diff to understand the change
23
+ - Write a short PR title (under 70 chars, imperative mood)
24
+ - Write the body using this format:
25
+ ```
26
+ ## Summary
27
+ <1-3 bullet points explaining the changes>
28
+
29
+ ## Changes
30
+ <bulleted list of key file/module changes>
31
+
32
+ ## Test plan
33
+ <how to verify the changes work>
34
+ ```
35
+
36
+ 5. **Present draft to user:**
37
+ - Show the proposed title and body
38
+ - Ask: "Push and create this PR?" with options: Yes (create), Edit (let me revise), Cancel
39
+
40
+ 6. **On approval:**
41
+ - Check if branch has upstream: `git rev-parse --abbrev-ref @{upstream}`
42
+ - Push branch: `git push -u origin HEAD`
43
+ - Create PR: `gh pr create --title "<title>" --body "<body>" --base <base>`
44
+ - Show the resulting PR URL
45
+
46
+ **On success, output:**
47
+ ```
48
+ ✓ Pushed branch: <branch-name>
49
+ ✓ Created PR: <pr-url>
50
+ ```
51
+
52
+ **Error handling:**
53
+ - If `gh` is not installed: "GitHub CLI (gh) is required. Install it: https://cli.github.com"
54
+ - If not authenticated: "Run `gh auth login` first."
55
+ - If PR already exists: show the existing PR URL with `gh pr view --web`
56
+ - If push fails: show the git error and abort
.claude/commands/finalize.md ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Finalize the current work: format, test, fix, commit, and push.
2
+
3
+ Run this command after making code changes to complete the development cycle. It handles formatting, testing (with auto-fix retries), committing, and pushing.
4
+
5
+ **Arguments:** $ARGUMENTS is an optional commit message override. If not provided, compose one automatically from the diff.
6
+
7
+ **Workflow:**
8
+
9
+ 1. **Format code**
10
+ - Run `uv run black ace/ tests/ examples/`
11
+
12
+ 2. **Update CLAUDE.md**
13
+ - Run `/init` to update the project's CLAUDE.md file with current codebase context
14
+
15
+ 3. **Review test coverage**
16
+ - Check if the changes have adequate test coverage
17
+ - Look at which lines/branches are untested for the modified files
18
+ - If coverage gaps exist for the changed code, add targeted tests before proceeding
19
+ - Focus on: new functions, error paths, edge cases, and branches introduced by this changeset
20
+
21
+ 4. **Run tests**
22
+ - Run `uv run pytest`
23
+
24
+ 5. **Test-fix loop (max 3 retries)**
25
+ - If tests pass, continue to step 6
26
+ - If tests fail:
27
+ - Analyze the failure output
28
+ - Fix the failing code or tests
29
+ - Add missing tests if the failures reveal gaps
30
+ - Re-run formatter: `uv run black ace/ tests/ examples/`
31
+ - Re-run tests: `uv run pytest`
32
+ - If tests still fail after 3 total attempts, **stop entirely** and report the failures. Never commit broken code.
33
+
34
+ 6. **Security review**
35
+ - Run `/security-review` to scan changed code for vulnerabilities
36
+ - If Critical or High severity issues are found, fix them before proceeding
37
+ - After fixing, re-run formatter (`uv run black ace/ tests/ examples/`) and tests (`uv run pytest`)
38
+ - If issues can't be auto-fixed, report them and stop
39
+
40
+ 7. **Review changes**
41
+ - Run `git diff` to review all changes
42
+ - Run `git status` to see untracked/modified files
43
+ - Determine which files to stage
44
+
45
+ 8. **Stage files selectively**
46
+ - Use explicit `git add <file>` for each file. **Never use `git add -A` or `git add .`**
47
+ - **Never stage:** `.env`, credentials, secrets, `__pycache__/`, `*.pyc`, large binaries, `.DS_Store`
48
+ - **Only stage `uv.lock`** if dependency changes in `pyproject.toml` were intentional
49
+ - If unsure about a file, ask the user
50
+
51
+ 9. **Compose commit message**
52
+ - If $ARGUMENTS was provided, use it as the commit message
53
+ - Otherwise, compose a Conventional Commit message: `<type>(<scope>): <short description>`
54
+ - Types: `feat`, `fix`, `refactor`, `test`, `docs`, `chore`, `perf`, `style`
55
+ - Derive scope from the primary changed file path (e.g., `ace/skillbook.py` -> `skillbook`, `ace/integrations/litellm.py` -> `integrations`, `tests/test_foo.py` -> `tests`)
56
+ - Keep messages short and imperative
57
+
58
+ 10. **Check branch safety**
59
+ - Run `git branch --show-current` to get the current branch
60
+ - If on `main` or `master`, **warn the user** and ask for explicit confirmation before committing
61
+ - If denied, stop without committing
62
+
63
+ 11. **Commit and push**
64
+ - Commit with the composed message
65
+ - Push to remote: `git push` (or `git push -u origin <branch>` if no upstream is set)
66
+
67
+ 12. **Report summary**
68
+ - Commit hash (short)
69
+ - Branch name
70
+ - Files changed count
71
+ - Test results (pass count)
72
+ - Any warnings encountered
73
+
74
+ **Error handling:**
75
+ - If no changes exist (clean working tree), report "Nothing to finalize" and stop
76
+ - If tests fail after 3 retries, report failures and stop without committing
77
+ - If push fails, report the error but keep the local commit
78
+ - If formatter fails, report the error and stop
79
+ - If security review finds unfixable Critical/High issues, report and stop without committing
.claude/commands/list-branches.md ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ List project branches with their worktree status.
2
+
3
+ **Arguments:** $ARGUMENTS (optional filters)
4
+ - No args: List all branches matching naming convention `<type>/<developer>/<description>`
5
+ - `--all`: Include all branches (not just convention-named)
6
+ - `--worktrees`: Only show branches with active worktrees
7
+ - `<type>`: Filter by type (feature, fix, docs, refactor, test, chore)
8
+
9
+ **Examples:**
10
+ - `/list-branches` → all convention-named branches
11
+ - `/list-branches feature` → only feature branches
12
+ - `/list-branches --worktrees` → only branches with worktrees
13
+ - `/list-branches --all` → all branches including main
14
+
15
+ **Steps:**
16
+ 1. Get all local branches: `git branch --format='%(refname:short)'`
17
+ 2. Get worktree list: `git worktree list --porcelain`
18
+ 3. Parse worktree output to map branches to paths
19
+ 4. Filter branches based on arguments
20
+ 5. Format and display results
21
+
22
+ **Output format:**
23
+ ```
24
+ Branch Worktree Status
25
+ ──────────────────────────────────────────────────────────────────────────────
26
+ * main . current
27
+ feature/john/add-caching ../feature-john-add-caching active
28
+ fix/jane/login-error (no worktree) -
29
+
30
+ Summary: 3 branches, 2 with worktrees
31
+ ```
32
+
33
+ **Column meanings:**
34
+ - `*` indicates current branch
35
+ - Worktree shows path relative to repo root, or "(no worktree)" if none
36
+ - Status: "current" (HEAD), "active" (has worktree), "-" (no worktree)
37
+
38
+ **Tips shown after output:**
39
+ - To create a worktree for a branch: `git worktree add ../<path> <branch>`
40
+ - To remove a branch with worktree: use `/remove-branch <branch>`
.claude/commands/release.md ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Release a new version: bump version, update changelog, tag, push, and create a GitHub release.
2
+
3
+ **Arguments:** $ARGUMENTS — the new version number (e.g. `0.9.0`). Required.
4
+
5
+ **Steps:**
6
+
7
+ 1. **Validate inputs**
8
+ - If $ARGUMENTS is empty, abort: "Usage: /release <version> (e.g. /release 0.9.0)"
9
+ - Strip leading `v` if present (e.g. `v0.9.0` → `0.9.0`)
10
+ - Validate format matches `X.Y.Z` (semver)
11
+
12
+ 2. **Validate branch state**
13
+ - Must be on `main`: `git branch --show-current`
14
+ - If not on main, abort: "Switch to main first."
15
+ - Pull latest: `git pull origin main`
16
+ - Working tree must be clean: `git status --porcelain`
17
+
18
+ 3. **Check version isn't already used**
19
+ - Read current version from `pyproject.toml` (line with `version = "..."`)
20
+ - If new version equals current version, abort: "Version <ver> is already set."
21
+ - Check tag doesn't exist: `git tag -l v<version>`
22
+ - If tag exists, abort: "Tag v<version> already exists."
23
+
24
+ 4. **Build changelog entry from git history**
25
+ - Find the latest tag: `git describe --tags --abbrev=0`
26
+ - Get commits since that tag: `git log <last-tag>..HEAD --format='%s'`
27
+ - Get merged PRs since that tag: `gh pr list --state merged --base main --search "merged:>=$(git log -1 --format=%ci <last-tag> | cut -d' ' -f1)" --json title,number --limit 50`
28
+ - From the commits/PRs, compose a changelog section with **only `### Added` items** — user-facing features. Skip fixes, refactors, chores, docs-only changes, and CI changes.
29
+ - Format:
30
+ ```
31
+ ## [X.Y.Z] - YYYY-MM-DD
32
+
33
+ ### Added
34
+ - **Feature name** — short description
35
+ - **Feature name** — short description
36
+ ```
37
+ - Also prepare a compare link for the bottom of CHANGELOG.md:
38
+ `[X.Y.Z]: https://github.com/Kayba-ai/agentic-context-engine/compare/v<prev>...vX.Y.Z`
39
+
40
+ 5. **Present draft to user**
41
+ - Show: new version, changelog entry, and the release note (same as changelog "Added" bullets)
42
+ - Ask: "Create this release?" with options: Yes, Edit (let me revise), Cancel
43
+
44
+ 6. **On approval — apply changes**
45
+ - Update `pyproject.toml`: replace `version = "<old>"` with `version = "<new>"`
46
+ - Insert the changelog entry in `CHANGELOG.md` after line 7 (before the previous release)
47
+ - Add the compare link at the bottom of CHANGELOG.md
48
+ - Stage files: `git add pyproject.toml CHANGELOG.md`
49
+ - Commit: `git commit -m "chore(release): bump version to <version>"`
50
+
51
+ 7. **Tag and push**
52
+ - `git tag v<version>`
53
+ - `git push origin main --tags`
54
+
55
+ 8. **Create GitHub release**
56
+ - Title: `v<version>`
57
+ - Notes: **only the "Added" bullets** from the changelog entry — short and clean, no preamble
58
+ - Append: `**Full Changelog**: https://github.com/kayba-ai/agentic-context-engine/compare/v<prev>...v<version>`
59
+ - Run: `gh release create v<version> --title "v<version>" --notes "<notes>"`
60
+ - This triggers `.github/workflows/publish.yml` → PyPI publish
61
+
62
+ 9. **Report summary**
63
+ ```
64
+ Released v<version>
65
+ - Commit: <short-hash>
66
+ - Tag: v<version>
67
+ - Release: <github-release-url>
68
+ - PyPI: publishing via workflow (check Actions tab)
69
+ ```
70
+
71
+ **Error handling:**
72
+ - If `gh` is not installed: "GitHub CLI (gh) is required. Install it: https://cli.github.com"
73
+ - If not authenticated: "Run `gh auth login` first."
74
+ - If push fails: report error, keep local commit (user can retry)
75
+ - If `gh release create` fails: show the error, suggest manual creation
.claude/commands/remove-branch.md ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Remove a branch and its associated worktree.
2
+
3
+ **Arguments:** $ARGUMENTS should be the branch name (full or partial match)
4
+ - `--force`: Skip confirmations and force delete unmerged branches
5
+
6
+ **Examples:**
7
+ - `/remove-branch feature/john/add-caching` → remove branch and worktree
8
+ - `/remove-branch add-caching` → partial match, will prompt to confirm
9
+ - `/remove-branch feature/john/add-caching --force` → skip all confirmations
10
+
11
+ **Steps:**
12
+ 1. Parse branch name and flags from arguments
13
+ 2. Resolve branch name (support partial matching if unique)
14
+ 3. Safety checks:
15
+ - Abort if trying to remove main/master
16
+ - Abort if trying to remove current branch (must switch first)
17
+ - Warn if branch has unmerged commits (show `git log main..<branch> --oneline`)
18
+ 4. Check if branch has an associated worktree: `git worktree list`
19
+ 5. If worktree exists:
20
+ - Remove worktree first: `git worktree remove <path>` (or `--force` if needed)
21
+ - Prune worktree list: `git worktree prune`
22
+ 6. Delete the branch: `git branch -d <branch>` (or `-D` with `--force`)
23
+ 7. Confirm success
24
+
25
+ **On success, output:**
26
+ ```
27
+ ✓ Removed worktree: <worktree-path>
28
+ ✓ Removed branch: <branch-name>
29
+ ```
30
+
31
+ **Error handling:**
32
+ - Multiple partial matches: list matches and ask user to be more specific
33
+ - Unmerged commits without --force: show commits and ask for confirmation
34
+ - Protected branches (main/master): refuse with explanation
35
+ - Current branch: instruct user to switch branches first
36
+
37
+ **Protected branches:** main, master
38
+
39
+ **Confirmation prompts (unless --force):**
40
+ - "Branch has N unmerged commits. Remove anyway? (show commits first)"
41
+ - For partial match: "Did you mean <full-branch-name>?"
.claude/package.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"type":"commonjs"}
.claude/projects/-home-david-projects-Kayba-agentic-context-engine/memory/feedback_bedrock_only.md ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ name: Always use Bedrock
3
+ description: Never use direct Anthropic API key or fall back to OpenAI — always use Bedrock via AWS_BEARER_TOKEN_BEDROCK
4
+ type: feedback
5
+ ---
6
+
7
+ Always use Bedrock for LLM calls. Never use the Anthropic API key directly, never fall back to OpenAI or any other provider.
8
+
9
+ **Why:** The user has Bedrock configured with `AWS_BEARER_TOKEN_BEDROCK` and does not want direct Anthropic API usage (burns quota/money on the wrong account). Fallback logic is unacceptable — it silently uses the wrong provider.
10
+
11
+ **How to apply:** In integration tests and any code that needs an LLM model string, use `bedrock/us.anthropic.claude-haiku-4-5-20251001-v1:0` (or similar Bedrock model). Never write fallback chains like "if ANTHROPIC_KEY else OPENAI". Just use Bedrock, period.
.claude/settings.json ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(uv run pytest:*)",
5
+ "Bash(uv run black:*)"
6
+ ]
7
+ }
8
+ }
.claude/skills/kayba-pipeline/SKILL.md ADDED
@@ -0,0 +1,145 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ name: kayba-pipeline
3
+ description: End-to-end agent evaluation and improvement pipeline. Takes a traces folder and optional HITL flag, then orchestrates sub-agents through 7 stages — each stage is its own skill invoked by a dedicated sub-agent. Trigger when the user says "run the pipeline", "kayba pipeline", "evaluate and fix", "full eval", "analyze traces and fix", or provides a traces folder with intent to improve their agent.
4
+ ---
5
+
6
+ # kayba-pipeline
7
+
8
+ End-to-end pipeline: analyze traces → define metrics → build rubric → plan fixes → implement fixes.
9
+
10
+ Each stage is a separate skill file that can be run independently or as part of this pipeline.
11
+
12
+ ## Inputs
13
+
14
+ The user provides two things:
15
+
16
+ 1. **`TRACES_FOLDER`** — path to a directory containing trace JSON files
17
+ 2. **`HITL`** — `true` or `false` — whether to pause for human review before implementing fixes
18
+
19
+ If the user doesn't specify HITL, default to `true` (safe default).
20
+
21
+ ---
22
+
23
+ ## Pipeline overview
24
+
25
+ ```
26
+ ┌─────────────────────────────────────────────────────────────────────┐
27
+ │ Stage 1: Kayba API Analysis → skill: kayba-pipeline:stage-1-api-analysis │
28
+ │ Stage 2: Domain Context Gathering → skill: kayba-pipeline:stage-2-domain-context │
29
+ │ ─── stages 1 & 2 run in parallel ─── │
30
+ │ Stage 3: Metrics & Analysis → skill: kayba-pipeline:stage-3-metrics │
31
+ │ Stage 4: Rubric Definition → skill: kayba-pipeline:stage-4-rubric │
32
+ │ Stage 5: Action Plan → skill: kayba-pipeline:stage-5-action-plan │
33
+ │ Stage 6: HITL Gate → skill: kayba-pipeline:stage-6-hitl │
34
+ │ Stage 7: Fix Implementation → skill: kayba-pipeline:stage-7-fixer │
35
+ └─────────────────────────────────────────────────────────────────────┘
36
+ ```
37
+
38
+ ---
39
+
40
+ ## Orchestration instructions
41
+
42
+ You are the orchestrator. Your job is to:
43
+ 1. Create the `eval/` directory and `eval/pipeline_log.md`
44
+ 2. Spawn sub-agents that invoke stage skills via the Skill tool
45
+ 3. Coordinate stage ordering and handle the HITL gate
46
+
47
+ ### Setup
48
+
49
+ Create `eval/` directory and initialize `eval/pipeline_log.md`:
50
+
51
+ ```markdown
52
+ # Pipeline Log
53
+
54
+ | Stage | Name | Status | Started | Completed | Notes |
55
+ |-------|------|--------|---------|-----------|-------|
56
+ | 1 | Kayba API Analysis | pending | | | |
57
+ | 2 | Domain Context | pending | | | |
58
+ | 3 | Metrics & Analysis | pending | | | |
59
+ | 4 | Rubric Definition | pending | | | |
60
+ | 5 | Action Plan | pending | | | |
61
+ | 6 | HITL Gate | pending | | | |
62
+ | 7 | Fix Implementation | pending | | | |
63
+ ```
64
+
65
+ ### Stages 1 & 2 — run in parallel
66
+
67
+ Spawn two sub-agents in parallel using the Agent tool:
68
+
69
+ **Agent 1:**
70
+ - Name: `api-analyst`
71
+ - Type: `general-purpose`
72
+ - Prompt: `Invoke the skill "kayba-pipeline:stage-1-api-analysis" using the Skill tool. The traces folder is: {TRACES_FOLDER}. Follow the skill instructions completely.`
73
+
74
+ **Agent 2:**
75
+ - Name: `domain-scout`
76
+ - Type: `general-purpose`
77
+ - Prompt: `Invoke the skill "kayba-pipeline:stage-2-domain-context" using the Skill tool. The traces folder is: {TRACES_FOLDER}. Follow the skill instructions completely.`
78
+
79
+ Wait for both to complete before proceeding.
80
+
81
+ ### Stage 3 — sequential
82
+
83
+ Spawn one sub-agent after stages 1 & 2 complete:
84
+
85
+ - Name: `metric-engineer`
86
+ - Type: `general-purpose`
87
+ - Prompt: `Invoke the skill "kayba-pipeline:stage-3-metrics" using the Skill tool. The traces folder is: {TRACES_FOLDER}. Follow the skill instructions completely — this includes iterating on the metrics until you're satisfied.`
88
+
89
+ ### Stage 4 — sequential
90
+
91
+ Spawn one sub-agent after stage 3 completes:
92
+
93
+ - Name: `rubric-builder`
94
+ - Type: `general-purpose`
95
+ - Prompt: `Invoke the skill "kayba-pipeline:stage-4-rubric" using the Skill tool. Follow the skill instructions completely.`
96
+
97
+ ### Stage 5 — sequential
98
+
99
+ Spawn one sub-agent after stage 4 completes:
100
+
101
+ - Name: `action-planner`
102
+ - Type: `general-purpose`
103
+ - Prompt: `Invoke the skill "kayba-pipeline:stage-5-action-plan" using the Skill tool. Follow the skill instructions completely.`
104
+
105
+ ### Stage 6 — HITL Gate
106
+
107
+ **If `HITL` is `true`:**
108
+
109
+ Spawn one sub-agent after stage 5 completes:
110
+
111
+ - Name: `hitl-reviewer`
112
+ - Type: `general-purpose`
113
+ - Prompt: `Invoke the skill "kayba-pipeline:stage-6-hitl" using the Skill tool. Follow the skill instructions completely. Present the full review to the user and collect their decision before proceeding.`
114
+
115
+ Wait for the sub-agent to complete. Check `eval/stage6_decision.md` for the outcome:
116
+ - If decision is "Approve all" or "Approve with modifications" — proceed to Stage 7
117
+ - If decision is "Reject" — re-run Stage 5 with the user feedback recorded in `eval/stage6_decision.md`, then re-run Stage 6
118
+ - Only proceed to Stage 7 after a clear approval is recorded
119
+
120
+ **If `HITL` is `false`:**
121
+ - Skip to Stage 7
122
+ - Log "HITL skipped" in `eval/pipeline_log.md`
123
+
124
+ ### Stage 7 — sequential
125
+
126
+ Spawn one sub-agent after stage 6 completes (or is skipped):
127
+
128
+ - Name: `fixer`
129
+ - Type: `general-purpose`
130
+ - Prompt: `Invoke the skill "kayba-pipeline:stage-7-fixer" using the Skill tool. Follow the skill instructions completely.`
131
+
132
+ ---
133
+
134
+ ## Error handling
135
+
136
+ - If any stage fails, log the failure in `eval/pipeline_log.md` with the stage number and error
137
+ - Do not proceed to dependent stages if a prerequisite failed
138
+ - If Stage 1 fails (kayba CLI issues), ask the user whether to proceed without API insights — if yes, skip Stage 1 and have Stage 3 work from domain context + raw traces only
139
+
140
+ ## After completion
141
+
142
+ Update `eval/pipeline_log.md` with final status for all stages. Report to the user:
143
+ - How many stages completed successfully
144
+ - Summary of metrics (from rubric)
145
+ - Summary of fixes applied (from changes log)
.claude/skills/kayba-pipeline/stage-1-api-analysis/SKILL.md ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ name: kayba-stage-1-api-analysis
3
+ description: Fetch pre-computed insights from the Kayba API and build a structured summary. Does NOT upload traces or trigger generation — analysis is assumed to already exist. Trigger when the user says "run stage 1", "get insights", "fetch skills", "kayba analyze", or when invoked by the kayba-pipeline orchestrator. Requires the kayba CLI to be installed and KAYBA_API_KEY to be set.
4
+ ---
5
+
6
+ # Stage 1: Kayba API Analysis (Fetch-Only Mode)
7
+
8
+ Fetch pre-computed insights from the Kayba API. Traces have already been uploaded and analyzed — this stage only pulls results.
9
+
10
+ ## Inputs
11
+
12
+ - **`TRACES_FOLDER`** — passed by the orchestrator but **ignored** in this stage. Traces are already uploaded and analyzed on the Kayba side. Do NOT upload, validate, or read trace files.
13
+
14
+ ## Process
15
+
16
+ ### Step 1: Setup
17
+
18
+ Ensure `eval/` directory exists at the project root.
19
+
20
+ ### Step 2: Fetch insights
21
+
22
+ ```
23
+ kayba insights list --json > eval/insights.json
24
+ ```
25
+
26
+ If `kayba` is not found in PATH, search common locations (`.venv/bin/kayba`, project virtualenvs). If found, use the full path. If not found anywhere, report the error and stop.
27
+
28
+ If `KAYBA_API_KEY` is not set, report the error and stop.
29
+
30
+ ### Step 3: Insight quality gate
31
+
32
+ Read `eval/insights.json` and run quality checks before building the summary:
33
+
34
+ 1. **Empty check**: if the insights array is empty (0 insights returned), report this as a warning. Write a minimal summary noting "0 insights generated" and stop — downstream stages cannot proceed without insights.
35
+ 2. **Duplicate detection**: compare insight `content` fields pairwise. If two insights cover substantially the same behavior (same section, overlapping evidence traces, similar corrective action), flag them as potential duplicates in the summary. Do not remove them — just annotate.
36
+ 3. **Evidence coverage**: for each insight, check if the `evidence` field references specific traces (e.g., "task_7 turn 4"). Insights with no trace-specific evidence are lower quality — flag as "low-evidence" in the summary.
37
+ 4. **Vote signal**: insights with `status: "accepted"` and `helpful > 0` have been human-validated. Insights with `status: "new"` and `helpful: 0, harmful: 0` are unvalidated — note this distinction in the summary.
38
+
39
+ Log the quality gate result: `"Insight quality: {total} insights, {accepted} accepted, {new_unvalidated} unvalidated, {duplicates} potential duplicate pairs, {low_evidence} low-evidence"`
40
+
41
+ ### Step 4: Build structured summary
42
+
43
+ Extract a structured summary of each insight:
44
+ - Insight ID and title/summary (use the `section` field as the title)
45
+ - Status
46
+ - Evidence citations — specific trace references, error strings, behavioral patterns the reflector identified
47
+ - Justification / reasoning chain — the reflector's full analysis of why this is a real pattern
48
+ - Confidence score if available
49
+ - Helpful/harmful counts if available
50
+ - Quality flags from Step 3 (potential duplicate, low-evidence, unvalidated)
51
+
52
+ Write the structured summary to `eval/stage1_insights_summary.md` using this format:
53
+
54
+ ```markdown
55
+ # Kayba Insights Summary
56
+
57
+ Generated from: Kayba API (pre-computed analysis)
58
+ Total insights: N
59
+ Quality: {accepted} accepted, {unvalidated} unvalidated, {duplicate_pairs} potential duplicate pairs, {low_evidence} low-evidence
60
+
61
+ ## Insight: [ID] — [section title]
62
+ **Status:** [status] [quality flags if any, e.g., "[potential duplicate with ID]", "[low-evidence]", "[unvalidated]"]
63
+ **Confidence:** [score if available]
64
+ **Evidence:**
65
+ - [citation 1 — trace reference, error string, or behavioral pattern]
66
+ - [citation 2]
67
+ **Justification:** [reflector's reasoning for why this is a real pattern]
68
+ **Helpful/Harmful:** [counts if available]
69
+
70
+ ---
71
+ [repeat for each insight]
72
+ ```
73
+
74
+ ## Error handling
75
+
76
+ - If `kayba` is not found in PATH or common locations, report the error and stop
77
+ - If `KAYBA_API_KEY` is not set, report the error and stop
78
+ - If `kayba insights list` fails (network error, auth error), report the error and stop
79
+ - If 0 insights are returned, write a minimal summary and stop — downstream stages need insights
80
+
81
+ ## Outputs
82
+
83
+ - `eval/insights.json` — raw API response
84
+ - `eval/stage1_insights_summary.md` — structured summary with quality annotations for downstream stages
.claude/skills/kayba-pipeline/stage-2-domain-context/SKILL.md ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ name: kayba-stage-2-domain-context
3
+ description: Gather domain context about the repository and agent — system prompt, tool definitions, domain docs, and behavior patterns from traces. Trigger when the user says "run stage 2", "gather context", "domain context", or when invoked by the kayba-pipeline orchestrator.
4
+ ---
5
+
6
+ # Stage 2: Domain Context Gathering
7
+
8
+ Understand the agent's world — what it does, what tools it has, and what "success" looks like.
9
+
10
+ ## Inputs
11
+
12
+ - **`TRACES_FOLDER`** — path to directory containing trace JSON files
13
+
14
+ ## Process
15
+
16
+ ### 0. Detect trace format
17
+
18
+ Before reading traces, identify the framework that produced them. Read 1 trace file and check:
19
+
20
+ | Signal | Framework |
21
+ |--------|-----------|
22
+ | `info.agent_info.implementation`, `info.environment_info`, `simulation.messages[]` with `role`/`tool_calls`/`turn_idx` | **tau2-bench** |
23
+ | `runs[].steps[]` with `type: "tool"`, `lc_kwargs` | **LangChain / LangSmith** |
24
+ | `events[]` with `event_type`, `span_id`, `parent_id` | **LlamaIndex** |
25
+ | `choices[].message.tool_calls[]` at top level | **Raw OpenAI API logs** |
26
+ | `trace.spans[]` with `attributes`, `trace_id` | **OpenTelemetry / Arize / Langfuse** |
27
+
28
+ Record the detected format in the output under **Trace Format**. All subsequent trace-reading steps use the field paths appropriate for that format.
29
+
30
+ If the format is unrecognized, note the top-level keys and structure, then proceed best-effort with field names found in the data.
31
+
32
+ ### 1. Detect architecture
33
+
34
+ Read 2-3 traces and determine if this is a single-agent or multi-agent system:
35
+
36
+ - **Single agent**: one `agent_info` entry, one conversation thread, tool calls from one identity
37
+ - **Multi-agent / router**: look for multiple `agent_info` entries, routing tool calls (e.g., `transfer_to_*`, `delegate_to_*`), sub-conversation arrays, or distinct system prompts per agent identity
38
+
39
+ If multi-agent: document each agent separately (name, role, tools, handoff triggers) and note the routing logic. The remaining steps apply per-agent.
40
+
41
+ ### 2. Find the system prompt
42
+
43
+ Use a fallback chain — stop at the first hit:
44
+
45
+ 1. **Config files** — grep for keys: `system_prompt`, `system_message`, `instructions`, `AGENT_INSTRUCTION`, `SYSTEM_PROMPT` in YAML/JSON/TOML/Python/JS files
46
+ 2. **Source code** — search for prompt template strings, f-strings, or `.format()` calls that build the system message (look in agent implementation files)
47
+ 3. **Trace extraction** — read 3 trace files from `{TRACES_FOLDER}`:
48
+ - Check `info.environment_info.policy` (tau2-bench format)
49
+ - Check first message with `role: "system"` in the messages array
50
+ - Check `raw_data` fields for system-level content
51
+ 4. **Not found** — if none of the above yields a system prompt, explicitly record `SYSTEM_PROMPT_STATUS: NOT_FOUND` in the output and flag this for the orchestrator. Do not fabricate or guess.
52
+
53
+ When found, record both the prompt content and its **source location** (file path + line, or trace field path).
54
+
55
+ ### 3. Extract tool definitions
56
+
57
+ Two-pass approach: source code first (ground truth), then traces (usage evidence).
58
+
59
+ **Pass 1 — Source code discovery:**
60
+ - Search for tool/function definition patterns: `@tool`, `@is_tool`, `def tool_`, function schema arrays, OpenAPI specs, `tools=[]` arguments
61
+ - For each tool, extract from source:
62
+ - Name
63
+ - Input parameters with types and defaults
64
+ - Return type / output schema (document the structure, not just "returns a dict")
65
+ - Side effects: READ (no state change), WRITE (mutates state), GENERIC (neither)
66
+ - Validation rules the tool does NOT enforce (critical — grep for comments like "API does not check", "agent must enforce")
67
+
68
+ **Pass 2 — Trace usage evidence:**
69
+ - Read ALL traces (if <= 20) or a stratified sample (see step 4 for sampling)
70
+ - Extract every unique `tool_calls[].name` from assistant messages
71
+ - Extract every `role: "tool"` response to document actual output shapes
72
+ - For each tool, record one example input/output pair from traces
73
+
74
+ **Reconcile the two passes:**
75
+ - Tools in source but NOT in traces = "available but unused" — flag these; they may be relevant for edge cases the agent should handle
76
+ - Tools in traces but NOT in source = possible dynamic tools or external APIs — investigate
77
+
78
+ Output the full tool inventory as a table with columns: Name, Category, Input Schema, Output Schema, Observed in Traces (Y/N), Unvalidated Rules.
79
+
80
+ ### 4. Find domain documentation
81
+
82
+ - READMEs, product docs, wiki links
83
+ - Policy files (e.g., `data/*/policy.md`, domain-specific docs)
84
+ - Inline code comments explaining business logic
85
+ - Test files that describe expected behavior
86
+ - Anything that explains what the agent does and what "success" means for its users
87
+
88
+ ### 5. Catalogue agent behavior patterns
89
+
90
+ **Trace selection — stratified sampling** (do not just grab "5-10 random traces"):
91
+
92
+ 1. Count total traces in `{TRACES_FOLDER}`. If <= 20, read ALL of them.
93
+ 2. If > 20, select a stratified sample:
94
+ - Sort by `termination_reason` — include at least 2 per unique reason
95
+ - Sort by conversation length (message count) — include shortest, longest, and 2 median
96
+ - Sort by tool call count — include lowest and highest
97
+ - If task outcomes are available (pass/fail), include at least 3 of each
98
+ - Target: ~15 traces total, or 30% of the corpus, whichever is larger
99
+
100
+ For each selected trace, document:
101
+ - **Function call frequency** — which tools are called most, in what order
102
+ - **Tool call sequences** — common tool chains (e.g., get_user -> get_reservation -> cancel)
103
+ - **Success patterns** — what does a thread that accomplishes its goal look like?
104
+ - **Failure patterns** — what does a thread that fails or gets stuck look like?
105
+ - **Error patterns** — what error strings appear in tool outputs? Group by root cause
106
+ - **Policy violation patterns** — where does the agent break its own rules? (e.g., multiple tool calls per turn, acting without confirmation)
107
+ - **User feedback signals** — reverts, ratings, explicit corrections, escalations, stop tokens, transfer tokens
108
+
109
+ ### 6. Write findings
110
+
111
+ Write all findings to `eval/stage2_domain_context.md`:
112
+
113
+ ```markdown
114
+ # Domain Context
115
+
116
+ ## Trace Format
117
+ - Framework: [detected framework name]
118
+ - Key field paths: [e.g., simulation.messages[], info.environment_info.policy]
119
+
120
+ ## Architecture
121
+ - Type: [single-agent | multi-agent]
122
+ - [If multi-agent: agent roster with roles and handoff triggers]
123
+
124
+ ## Agent Purpose
125
+ [1-2 sentence summary of what this agent does]
126
+
127
+ ## System Prompt
128
+ - **Source**: [file path + line, or trace field path, or NOT_FOUND]
129
+ - **Status**: [verbatim | reconstructed | not_found]
130
+
131
+ [The system prompt content, or "NOT_FOUND — downstream stages should account for missing system prompt"]
132
+
133
+ ## Tools
134
+ | Tool | Category | Input Schema | Output Schema | In Traces? | Unvalidated Rules |
135
+ |------|----------|-------------|---------------|------------|-------------------|
136
+ | tool_name | READ/WRITE/GENERIC | `{param: type}` | `{field: type}` | Y/N | "API does not check X" |
137
+
138
+ ### Tools available but never called in traces
139
+ - [tool_name — why it matters]
140
+
141
+ ## Domain Rules
142
+ [Key business rules, constraints, policies the agent must follow]
143
+
144
+ ## Behavior Patterns
145
+
146
+ ### Success patterns
147
+ - [pattern 1]
148
+
149
+ ### Failure patterns
150
+ - [pattern 1]
151
+
152
+ ### Policy violation patterns
153
+ - [violation with frequency: N/M turns]
154
+
155
+ ### Error patterns
156
+ | Error | Frequency | Root cause |
157
+ |-------|-----------|------------|
158
+ | error string | N traces | cause |
159
+
160
+ ### User feedback signals
161
+ - [signal 1]
162
+ ```
163
+
164
+ ## Outputs
165
+
166
+ - `eval/stage2_domain_context.md`
.claude/skills/kayba-pipeline/stage-3-metrics/SKILL.md ADDED
@@ -0,0 +1,180 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ name: kayba-stage-3-metrics
3
+ description: Define metrics from Kayba insights, implement them as Python measurement code, run against traces, and iterate until the metrics are clean and meaningful. Trigger when the user says "run stage 3", "define metrics", "build metrics", "compute baselines", or when invoked by the kayba-pipeline orchestrator. Requires eval/stage1_insights_summary.md and eval/stage2_domain_context.md to exist.
4
+ ---
5
+
6
+ # Stage 3: Metrics and Programmatic Analysis
7
+
8
+ Define metrics from insights, implement as code, run, review, iterate.
9
+
10
+ ## Inputs
11
+
12
+ - **`TRACES_FOLDER`** — path to directory containing trace JSON files
13
+ - **`eval/stage1_insights_summary.md`** — output from Stage 1
14
+ - **`eval/stage2_domain_context.md`** — output from Stage 2
15
+
16
+ Read both input files before starting.
17
+
18
+ ## Process
19
+
20
+ This stage is iterative. You cycle through define → implement → run → review, with a hard cap of **3 iterations**. A metric set is "clean" when ALL of the following hold:
21
+
22
+ 1. **No small-sample metrics in the priority set** — every metric used for priority ranking has denominator >= 5. Metrics with denominator < 5 are kept but labeled `"confidence": "directional-only"` and excluded from priority sorting.
23
+ 2. **No unexplained extremes** — no metric reads 0% or 100% unless you can write a one-sentence justification (e.g., "0% is correct because the agent never calls send_certificate anywhere in the dataset"). Record the justification in the metric's `"extreme_justification"` field.
24
+ 3. **No redundant pairs** — no two metrics share > 70% of their denominator events. Check this: for each pair, compute `|events_A ∩ events_B| / min(|events_A|, |events_B|)`. If > 0.70, merge or drop one.
25
+ 4. **Script runs without errors** on the full trace set.
26
+
27
+ If after 3 iterations the set is not fully clean, ship what you have and log remaining issues in `eval/baseline_metrics.json` under a top-level `"warnings"` key.
28
+
29
+ ### Step 1: Define metrics
30
+
31
+ For each insight from the Kayba analysis, use the evidence fields to identify observable signals in the traces:
32
+
33
+ 1. Read the insights summary — focus on evidence citations, error strings, behavioral patterns
34
+ 2. For each valid insight, determine what trace signal would change if the agent followed the skill
35
+ 3. Classify each metric by detector pattern type:
36
+
37
+ **Recovery detectors** — consecutive calls to the same function where first has error, next succeeds
38
+ ```python
39
+ def has_recovery(calls, function_name):
40
+ for i in range(len(calls) - 1):
41
+ if calls[i]['name'] == function_name and is_error(calls[i]['output']):
42
+ if calls[i+1]['name'] == function_name and is_success(calls[i+1]['output']):
43
+ return True
44
+ return False
45
+ ```
46
+
47
+ **Loop detectors** — N+ consecutive calls to the same function (stuck agent)
48
+
49
+ **Give-up detectors** — regex match agent output for abandonment phrases ("I'm unable to", "cannot complete", "beyond my capabilities")
50
+
51
+ **Error classifiers** — match function outputs against domain-specific error patterns. Build a pattern table:
52
+ ```python
53
+ ERROR_PATTERNS = {
54
+ 'pattern_name': r'regex matching the error',
55
+ # one entry per distinct error type
56
+ }
57
+ ```
58
+
59
+ **Over-exploration detectors** — ratio of explore vs action calls. Use the tool categories from Stage 2. If explore ratio exceeds threshold AND task didn't complete → analysis paralysis
60
+
61
+ **Ground-truth comparison detectors** — agent claims a value (dollar amount, flight number, policy rule) in natural language, and the preceding tool response contains the actual value. Extract candidate values from agent text via regex, then compare against structured fields in the tool response JSON. Examples:
62
+ ```python
63
+ # Extract dollar amounts from agent text
64
+ DOLLAR_PATTERN = r'\$\s?([\d,]+(?:\.\d{2})?)'
65
+
66
+ # Extract flight numbers (3 letters + 3 digits)
67
+ FLIGHT_PATTERN = r'\b([A-Z]{2,3}\d{3,4})\b'
68
+
69
+ def check_agent_claims_against_tool(agent_text, preceding_tool_response):
70
+ """Compare values the agent states against the tool response ground truth."""
71
+ claimed_amounts = re.findall(DOLLAR_PATTERN, agent_text)
72
+ actual_amounts = extract_amounts_from_json(preceding_tool_response)
73
+ # A claim is fabricated if it doesn't match any actual value
74
+ fabricated = [c for c in claimed_amounts if not any(matches(c, a) for a in actual_amounts)]
75
+ return len(fabricated) == 0, fabricated
76
+ ```
77
+ This pattern covers data accuracy (fabricated prices/flights), post-action verification (quoted vs actual cost), and policy accuracy (claimed restrictions vs policy text). These are NOT qualitative-only — regex + JSON comparison is noisy but produces a real signal. Build the detector even if it's imperfect; a noisy metric that produces a fix is better than a clean classification that produces nothing.
78
+
79
+ **Ordering/sequencing detectors** — agent performs actions in the wrong order (e.g., searches for flights before checking if the reservation is even modifiable). Check whether tool call A appears before tool call B when B should come first.
80
+
81
+ **Clean success** — threads where all tasks completed with no errors and no other tags
82
+
83
+ 4. **Validate each detector before coding it at scale.** Pick 2-3 traces where you already know the ground truth from Stage 1 evidence. Run your detector logic mentally (or in a scratch script) against those traces. If it misclassifies any of them, fix the logic before writing the full implementation. This catches regex and pattern bugs early — the Stage 3 trace showed multiple iterations wasted on broken confirmation-phrase matching that a quick manual check would have caught.
84
+
85
+ ### Step 2: Implement and run
86
+
87
+ 1. Write `eval/compute_baselines.py` with:
88
+ - CLI args: `--traces-dir` (required), `--output` (default: `eval/baseline_metrics.json`)
89
+ - `load_traces(traces_dir)` — loads all JSON trace files
90
+ - Error pattern table built from reading 20-30 traces
91
+ - `tag_thread(thread)` — combines all detectors, returns list of tags
92
+ - One measurement function per metric, computing `numerator / denominator`
93
+ - `compute_all_baselines(traces_dir)` — runs all metrics, returns dict
94
+ - Main block that runs everything and prints summary
95
+
96
+ 2. Run it:
97
+ ```
98
+ python eval/compute_baselines.py --traces-dir {TRACES_FOLDER} --output eval/baseline_metrics.json
99
+ ```
100
+
101
+ ### Step 3: Review and iterate
102
+
103
+ Run these checks in order after every run. Each check either passes or produces a concrete fix action.
104
+
105
+ **Check A — Script health.** Did the script error or produce `null` values? → fix and re-run. This is iteration 0-cost; don't count it toward the 3-iteration cap.
106
+
107
+ **Check B — Small-sample guard.** For each metric, examine the denominator:
108
+ - denominator >= 5 → full-confidence metric, usable for priority ranking
109
+ - denominator 1-4 → label `"confidence": "directional-only"` in the output JSON. The metric stays in the report but is excluded from priority sorting in Stage 4. Do NOT drop it — small-sample metrics can still inform qualitative analysis.
110
+ - denominator 0 → the detector found no applicable events. Either the detector is broken (fix it) or the behavior genuinely doesn't occur in this trace set (log as `"confidence": "not-observed"` and move on).
111
+
112
+ **Check C — Extreme-value triage.** For any metric at exactly 0% or 100%:
113
+ - Ask: "Is there a plausible trace where this metric would NOT be extreme?" If yes → detector is likely broken, fix it.
114
+ - If no (the behavior legitimately always/never happens in this dataset) → write a one-sentence justification and add it as `"extreme_justification"` in the output. Example: M5=0% is correct because both cancellations in the dataset were on ineligible reservations.
115
+ - Do NOT reflexively drop 0%/100% metrics. A metric that correctly reads 0% is a strong signal for Stage 5 action planning.
116
+ - **Ceiling/floor flag for 100% and 0% metrics:** If a metric baseline is already at 100% (or 0% where 0% is the desired direction), add `"at_ceiling": true` (or `"at_floor": true`) to its entry in the output JSON. This signals to Stage 4 (direction setting) and Stage 5 (action planning) that the metric is already optimal and should NOT be listed as needing improvement. Stage 4 must set its direction to `"↑ maintain"` or `"— already optimal"`, never bare `"↑"`.
117
+
118
+ **Check D — Correlation / overlap audit.** For every pair of metrics, compute event overlap: `|denom_A ∩ denom_B| / min(|denom_A|, |denom_B|)`. If > 0.70:
119
+ - The two metrics are measuring overlapping populations. Keep the one with the sharper behavioral distinction (measures a more specific failure mode). Drop or merge the other.
120
+ - In the Stage 3 trace, M1 and M2 shared identical denominators (29 tool-calling turns) and were never flagged. They survived because they measure different *properties* of the same events — this is acceptable only if the numerator overlap is also checked. If both numerators move in lockstep (one is a strict subset of the other), merge them.
121
+
122
+ **Check E — Coverage (strict).** For EVERY Stage 1 insight, verify it has a corresponding metric. If an insight has no metric:
123
+ - First, try harder to build one. Can you extract values from agent text and compare against tool responses? Can you detect the wrong tool-call ordering? Can you pattern-match the failure mode with keywords + JSON field checks?
124
+ - Only after a concrete failed attempt, classify as unmeasurable with a specific reason why the approach you tried doesn't work.
125
+ - An insight classified as unmeasurable means Stage 5 will NOT produce a fix for it. That is a real cost. Treat every unmeasurable classification as a missed fix.
126
+
127
+ After checks, if any produced a fix action: apply fixes and re-run (counts as one iteration). If all checks pass → the metric set is clean. **Stop iterating.**
128
+
129
+ ### Design principles
130
+
131
+ - **Target one metric per insight.** Every insight should have a metric unless it is genuinely unmeasurable (see above). If you end up with fewer metrics than insights, you are being too conservative. Directional-only metrics (denominator < 5) still count — they produce fixes in Stage 5. Only apply the redundancy check (Check D) to merge metrics that truly overlap; do not use the metric count as a reason to skip building detectors.
132
+ - **Express every metric as a ratio or percentage.** Absolute counts aren't comparable across trace sets.
133
+ - **Prefer per-event denominators over per-thread.** "% of EditScript calls with errors" is sharper than "% of threads with any EditScript error." Per-thread denominators compress information — a thread with 10 violations and a thread with 1 both count the same.
134
+ - **One metric per behavioral change.** If two would always move together, keep only the sharper one. Use Check D (overlap audit) to enforce this mechanically, not just by intuition.
135
+ - **Build a metric for EVERY insight. "Unmeasurable" is a last resort, not a default.** Before classifying an insight as unmeasurable, you MUST attempt to build a programmatic detector. The bar for "unmeasurable" is: you tried a concrete approach, it fundamentally cannot work (not just "it's noisy"), and you can explain why in one sentence.
136
+
137
+ Specifically:
138
+ - **"Agent claims X but tool response says Y"** — this is ALWAYS measurable. Use regex to extract values (dollar amounts, IDs, flight numbers) from agent text, compare against structured JSON fields in the preceding tool response. Noisy matches are fine — a metric that catches 70% of fabrications is far more useful than a qualitative note that catches 0%.
139
+ - **"Agent violates policy rule Z"** — if the policy rule can be stated as a condition on trace data (tool call ordering, presence/absence of a call, argument values), build a detector. Only classify as qualitative-only if the rule requires understanding the *meaning* of free-text agent output beyond keyword/pattern matching.
140
+ - **"Insufficient data"** — if the detector logic is clear but n < 5, build the detector anyway and label it `"confidence": "directional-only"`. Do NOT skip building the metric. A directional-only metric still produces a fix in Stage 5.
141
+
142
+ If after genuine effort an insight truly cannot be measured programmatically, classify it as:
143
+ - `"qualitative-only"` — requires semantic understanding that regex/JSON comparison cannot approximate. Must explain what specific semantic judgment is needed and why pattern matching fails.
144
+ - `"insufficient-data"` — detector exists but denominator is 0 (not just small — literally zero applicable events). Note what scenarios would need to appear in traces.
145
+ - `"needs-ground-truth"` — requires task-specific expected outcomes that aren't in the trace format.
146
+
147
+ Record any remaining unmeasurable insights in the output JSON under a `"unmeasurable"` key. **The goal is for this list to be as short as possible — ideally empty.**
148
+
149
+ ## Outputs
150
+
151
+ - `eval/compute_baselines.py` — runnable script with `--traces-dir` and `--output` CLI args
152
+ - `eval/baseline_metrics.json` — computed baseline values, structured as:
153
+ ```json
154
+ {
155
+ "M1": {
156
+ "name": "single_tool_call_compliance",
157
+ "value": 0.414,
158
+ "numerator": 12,
159
+ "denominator": 29,
160
+ "confidence": "full"
161
+ },
162
+ "M5": {
163
+ "name": "cancellation_policy_compliance",
164
+ "value": 0.0,
165
+ "numerator": 0,
166
+ "denominator": 2,
167
+ "confidence": "directional-only",
168
+ "extreme_justification": "0% correct: both cancellations in dataset were on ineligible reservations"
169
+ },
170
+ "warnings": ["M5 and M6 have denominator < 5; excluded from priority ranking"],
171
+ "unmeasurable": [
172
+ {
173
+ "insight_id": "d7494740",
174
+ "name": "Cabin Change Constraints",
175
+ "classification": "insufficient-data",
176
+ "reason": "Only 1 update_reservation_flights call in dataset"
177
+ }
178
+ ]
179
+ }
180
+ ```
.claude/skills/kayba-pipeline/stage-4-rubric/SKILL.md ADDED
@@ -0,0 +1,163 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ name: kayba-stage-4-rubric
3
+ description: Organize computed metrics into a tiered evaluation rubric with leading, lagging, and quality indicators. Trigger when the user says "run stage 4", "build rubric", "tier metrics", or when invoked by the kayba-pipeline orchestrator. Requires eval/baseline_metrics.json and eval/compute_baselines.py to exist.
4
+ ---
5
+
6
+ # Stage 4: Rubric Definition
7
+
8
+ Organize metrics into a tiered evaluation rubric. Detect and resolve redundancy quantitatively. Ensure every insight is accounted for.
9
+
10
+ ## Inputs
11
+
12
+ - `eval/baseline_metrics.json` — computed baseline values from Stage 3
13
+ - `eval/compute_baselines.py` — to understand what each metric measures
14
+ - `eval/stage1_insights_summary.md` — the original insights
15
+ - `eval/stage2_domain_context.md` — domain context
16
+
17
+ Read all four files before starting.
18
+
19
+ ## Process
20
+
21
+ ### 1. Quantitative redundancy check
22
+
23
+ Before tiering, check every pair of metrics for overlap. Two metrics are redundancy candidates if ANY of the following hold:
24
+
25
+ - **Denominator overlap >70%**: compute `|denom_events(A) ∩ denom_events(B)| / min(|denom(A)|, |denom(B)|)`. If >0.70, they are candidates. To compute this, trace through the detector functions in `compute_baselines.py` and determine which trace events (turns, calls, threads) each denominator iterates over. When denominators are identical sets (same loop, same filter), overlap is 100%.
26
+ - **Same skill set**: the metrics map to the exact same set of insight/skill IDs from Stage 1.
27
+ - **Logical subsumption**: one metric's positive case is a strict subset of the other's (e.g., "turn has exactly 1 tool call" is a subset of "turn has no user-facing content alongside tool calls" only if every single-call turn also has no content — check this, don't assume it).
28
+
29
+ For each candidate pair, make an explicit decision with reasoning:
30
+
31
+ | Pair | Denom overlap | Skill overlap | Subsumption? | Decision | Reasoning |
32
+ |------|---------------|---------------|--------------|----------|-----------|
33
+ | M1/M2 | 100% (same 29 turns) | identical | No — can violate one without the other | **Keep both** | Independently actionable: batching vs. content leaking are distinct fixes |
34
+
35
+ Valid decisions: **keep both** (with reasoning why they're independently actionable), **merge** (combine into one metric, specify how), or **drop** (specify which and why). "They feel different" is not sufficient reasoning — cite the specific behavior that one catches and the other misses.
36
+
37
+ Final count target: 5-7 metrics after redundancy resolution.
38
+
39
+ ### 2. Tier each metric
40
+
41
+ Use this decision flowchart for every metric:
42
+
43
+ ```
44
+ Q1: Can a SINGLE skill/instruction change directly move this metric?
45
+ → If the agent follows one new instruction and the metric improves,
46
+ regardless of other behaviors: LEADING.
47
+
48
+ Q2: Does moving this metric require MULTIPLE skills to be adopted together?
49
+ → If improvement depends on several upstream behaviors all working
50
+ (e.g., proper turn structure + confirmation flow + execution):
51
+ LAGGING.
52
+
53
+ Q3: Does moving this metric require domain reasoning beyond following instructions?
54
+ → If the agent needs to correctly interpret policy rules, evaluate
55
+ eligibility criteria, or make judgment calls that can't be reduced
56
+ to a single instruction: QUALITY.
57
+ ```
58
+
59
+ Apply the flowchart to each metric and record the Q1/Q2/Q3 answer that determined the tier. If a metric could arguably be two tiers, pick the lower one (Leading < Lagging < Quality) and note the ambiguity.
60
+
61
+ Tier summary for reference:
62
+
63
+ | Tier | Purpose | Moves when... | Diagnostic signal |
64
+ |------|---------|---------------|-------------------|
65
+ | **Leading** | Behaviors a single skill directly changes | Skill is adopted | If leading moves but lagging doesn't → skill adopted but not solving the right problem |
66
+ | **Lagging** | Aggregate outcomes requiring multiple skills | Multiple skills coordinate | If lagging moves but leading doesn't → something else improved, not your skills |
67
+ | **Quality** | Requires domain understanding, not just instruction-following | Agent reasons correctly | If quality moves but lagging doesn't → agent got lucky or metric is mis-tiered |
68
+
69
+ ### 3. Flag low-confidence baselines
70
+
71
+ Any metric with denominator < 5 events is a **low-confidence baseline**. These metrics:
72
+ - ARE included in the rubric (they measure real behaviors)
73
+ - Are marked with `**Confidence: low** (n=X)` in the rubric
74
+ - Must NOT drive priority decisions in Stage 5 — they inform direction only
75
+ - Should note what denominator size would make them reliable (rule of thumb: n >= 10 for a rate metric to be meaningful, n >= 30 for statistical comparisons)
76
+
77
+ ### 4. Set direction
78
+
79
+ For each metric, indicate whether it should go **up higher** or **down lower**. Don't set arbitrary numerical targets — baseline + direction is enough.
80
+
81
+ **Ceiling guard:** If a metric's baseline is already 100%, its direction MUST be `"��� maintain"` or `"— already optimal"`, never `"↑"` as if it needs to go higher. A 100% metric is at ceiling — the goal is to sustain it, not improve it. Similarly, if a metric is at 0% and the desired direction is `"↓"`, mark it `"↓ maintain"` or `"— already at floor"`. Do not let any downstream stage (Stage 5 action plan, Stage 7 fixes) list a ceiling/floor metric as needing improvement.
82
+
83
+ ### 5. Map insights to metrics (completeness check)
84
+
85
+ For every insight from `eval/stage1_insights_summary.md`, assign it to one of three categories:
86
+
87
+ 1. **Mapped** — directly linked to one or more metrics. List which ones.
88
+ 2. **Indirectly mapped** — supports a metric but isn't the primary driver. List the metric and explain the indirect relationship.
89
+ 3. **Qualitative-only** — no programmatic metric captures this insight. Explicitly mark it and state why (e.g., "requires LLM-as-judge," "measures explanation quality," "efficiency pattern with no clear denominator").
90
+
91
+ Every insight MUST appear in exactly one category. If you find an insight that should have a metric but doesn't, note it as a gap for future Stage 3 iterations — but do not invent metrics at this stage.
92
+
93
+ At the end, report:
94
+ - `X / N insights mapped to metrics`
95
+ - `Y / N insights indirectly mapped`
96
+ - `Z / N insights qualitative-only`
97
+
98
+ ### 6. Add invalidation notes
99
+
100
+ For each metric, write one sentence answering: "What would make this tier assignment wrong?"
101
+
102
+ Examples:
103
+ - M1 (Leading): "Wrong if fixing batching also requires the agent to change its confirmation flow — that would make it Lagging."
104
+ - M5 (Quality): "Wrong if cancellation compliance can be fixed by a single checklist instruction without requiring the agent to reason about policy — that would make it Leading."
105
+
106
+ These notes exist so Stage 5 can catch tier errors. If Stage 5 finds evidence that a tier is wrong (e.g., a single skill would move a "Quality" metric), it should flag the conflict rather than silently inheriting the error.
107
+
108
+ ### 7. Write the rubric
109
+
110
+ Write to `eval/baseline_metrics.md`:
111
+
112
+ ```markdown
113
+ # Eval Rubric — Baseline Metrics
114
+
115
+ ## Summary
116
+ | # | Metric | Tier | Baseline | Direction | Confidence |
117
+ |---|--------|------|----------|-----------|------------|
118
+ | M1 | First-call success rate | Leading | 37.6% | up | ok (n=29) |
119
+ | M2 | ... | ... | ... | ... | ... |
120
+
121
+ ## Tier Definitions
122
+
123
+ - **Leading** — Single skill directly moves this. Should change first after deployment.
124
+ - **Lagging** — Multiple skills must coordinate. Improves as a consequence of adoption.
125
+ - **Quality** — Requires domain reasoning beyond instruction-following. Hardest to move.
126
+
127
+ ## Metric Details
128
+
129
+ ### M1: [name]
130
+ **Tier:** Leading
131
+ **Baseline:** 37.6% (685 / 1,821)
132
+ **Confidence:** ok (n=1821) | low (n=X) — needs n>=Y for reliable comparison
133
+ **Direction:** up higher is better
134
+ **What it measures:** [description]
135
+ **How it's computed:** [reference to function in compute_baselines.py]
136
+ **Skills that should move this:** [list insight/skill IDs from stage 1]
137
+ **Tier rationale:** [which flowchart question determined the tier]
138
+ **Invalidation note:** [what would make this tier wrong]
139
+
140
+ ### M2: [name]
141
+ ...
142
+
143
+ ## Redundancy Analysis
144
+
145
+ | Pair | Denom overlap | Skill overlap | Subsumption? | Decision | Reasoning |
146
+ |------|---------------|---------------|--------------|----------|-----------|
147
+ | ... | ... | ... | ... | ... | ... |
148
+
149
+ ## Insight Coverage
150
+
151
+ ### Mapped (X / N)
152
+ - `insight_id` — [title] → M1, M3
153
+
154
+ ### Indirectly mapped (Y / N)
155
+ - `insight_id` — [title] → supports M5 via [explanation]
156
+
157
+ ### Qualitative-only (Z / N)
158
+ - `insight_id` — [title] — [why no metric: e.g., "requires LLM-as-judge"]
159
+ ```
160
+
161
+ ## Outputs
162
+
163
+ - `eval/baseline_metrics.md` — human-readable tiered rubric with redundancy analysis, confidence flags, insight coverage, and invalidation notes
.claude/skills/kayba-pipeline/stage-5-action-plan/SKILL.md ADDED
@@ -0,0 +1,201 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ name: kayba-stage-5-action-plan
3
+ description: Triage each insight into discard/code-fix/prompt-fix and produce a prioritized action plan with specific recommendations. Trigger when the user says "run stage 5", "make action plan", "triage skills", or when invoked by the kayba-pipeline orchestrator. Requires eval outputs from stages 1-4.
4
+ ---
5
+
6
+ # Stage 5: Action Plan
7
+
8
+ Triage each insight and produce a concrete, prioritized action plan.
9
+
10
+ ## Inputs
11
+
12
+ - `eval/stage1_insights_summary.md` — insights from Kayba
13
+ - `eval/stage2_domain_context.md` — domain context
14
+ - `eval/baseline_metrics.md` — the evaluation rubric
15
+ - `eval/baseline_metrics.json` — baseline values
16
+ - `eval/compute_baselines.py` — measurement code
17
+
18
+ Read all files before starting.
19
+
20
+ ## Process
21
+
22
+ ### 1. Triage each insight
23
+
24
+ For each insight/skill, answer three questions in order: Is it valid? Is it already handled? Is it a code fix or prompt fix?
25
+
26
+ #### 1a. Validity check
27
+
28
+ - Does it describe a real, recurring problem visible in traces — or noise from a one-off edge case?
29
+ - Is it actionable — can the agent actually change this behavior given its tools and context?
30
+ - If not valid → verdict: **discard** with a one-sentence reason.
31
+
32
+ #### 1b. "Already handled" verification
33
+
34
+ Do not rely on memory or assumption. Run these checks and cite what you find:
35
+
36
+ 1. **Grep the codebase** for 2-3 key terms from the insight (tool names, error strings, behavioral keywords). Example: for an insight about cancellation eligibility, grep for `cancel`, `eligibility`, `criteria`.
37
+ 2. **Read the existing system prompt text** — check `AGENT_INSTRUCTION` in the agent file and the domain policy file. Quote any existing language that addresses this behavior.
38
+ 3. **Verdict:**
39
+ - If existing text partially covers it → **keep** as a strengthening fix, note what's missing.
40
+ - If no existing coverage → **keep**.
41
+ - If existing prompt text already covers the behavior thoroughly AND the baseline metric is >= 95% → **discard** (cite the existing text and metric). A high baseline alone is NOT sufficient to discard — if the metric is below 95%, there are still failures to fix. An 87% baseline means 1 in 8 attempts still fails; that is worth fixing.
42
+
43
+ #### 1c. Code-vs-prompt decision tree
44
+
45
+ Walk through this tree for every non-discarded insight:
46
+
47
+ ```
48
+ Q1: Can the agent fix this by following different instructions?
49
+ (Does it have the right tools, correct data in tool responses,
50
+ and sufficient context to behave correctly?)
51
+
52
+ ├─ YES → PROMPT FIX
53
+ │ The agent has everything it needs but acts wrong.
54
+ │ A system prompt addition would fix it.
55
+
56
+ └─ NO → Q2: What is the agent missing?
57
+
58
+ ├─ Tool doesn't exist, schema is wrong, API returns
59
+ │ incomplete data, infrastructure drops information,
60
+ │ timeout/error not surfaced to agent
61
+ │ → CODE FIX
62
+ │ Name the file, function, and specific change.
63
+
64
+ └─ The agent has partial information but the prompt
65
+ can't fully compensate (e.g., needs a new tool
66
+ but a heuristic prompt workaround exists)
67
+ → PROMPT FIX (primary) + CODE FIX (optional)
68
+ Note both. Mark the code fix as "optional" with
69
+ a one-sentence justification for why it's lower priority.
70
+ ```
71
+
72
+ **Ambiguity default:** When genuinely uncertain, default to **prompt fix** and add a note: `"Classification uncertain — defaulting to prompt fix. Revisit if prompt change doesn't move metrics."` This is safer because prompt fixes are cheaper to test and revert, and Stage 7 handles prompt fixes and code fixes through different paths.
73
+
74
+ Use the reflector's reasoning from Stage 1 insights — it often explicitly identifies root causes that clarify the code-vs-prompt distinction.
75
+
76
+ ### 2. Consolidate related insights
77
+
78
+ Before writing recommendations, merge insights that are redundant. Two insights should merge when ALL three conditions hold:
79
+
80
+ 1. **Same target behavior** — they describe the agent doing (or failing to do) the same thing.
81
+ 2. **Overlapping fix text** — the prompt instructions you'd write for each would share >50% of their content.
82
+ 3. **Addressing one substantially addresses the other** — fixing insight A would fix >80% of the cases described by insight B.
83
+
84
+ **When NOT to merge** — two insights about the same tool or domain area but different failure modes should remain separate. Example: "agent doesn't check cancellation eligibility" and "agent doesn't execute cancellation after user confirms" both involve `cancel_reservation` but are completely different behavioral failures with different prompt fixes. Keep them separate.
85
+
86
+ For each merge, document:
87
+ - Which insight IDs are combined
88
+ - Which insight's framing is primary (use the one with stronger trace evidence)
89
+ - What, if anything, is lost from the secondary insight (add it as a sub-point)
90
+
91
+ ### 3. Write specific recommendations
92
+
93
+ For each insight (after merging):
94
+
95
+ - **Discards:** one sentence on why it's not valid or actionable.
96
+ - **Code fixes:** what code/schema/infrastructure to change. Name the file, the function, the specific change. If Stage 7 needs to find the right code location, give it enough to grep for.
97
+ - **Prompt fixes:** the exact instruction text to add to the system prompt, where it should go (e.g., appended to `AGENT_INSTRUCTION`, added to domain policy, or as a standalone skill block), and why this wording over alternatives.
98
+
99
+ ### 4. Assess risk per fix
100
+
101
+ For each non-discarded fix, assess whether the change could break currently-working behaviors:
102
+
103
+ | Risk | Definition | Example |
104
+ |------|-----------|---------|
105
+ | **None** | Change is additive; no existing behavior could be affected | Adding a new metric to compute_baselines.py |
106
+ | **Low** | Change targets a behavior that is currently failing; working cases are unrelated | Adding a cancellation checklist when current cancellation compliance is 0% |
107
+ | **Medium** | Change modifies a behavior where some cases already work correctly | Strengthening confirmation protocol when 28.6% already succeed — could the new wording break the working 28.6%? |
108
+ | **High** | Change rewrites or constrains a behavior that mostly works | Restricting tool-call patterns when 41.4% already comply — overly rigid wording could cause the agent to under-call tools |
109
+
110
+ For Medium and High risk fixes, add a one-sentence mitigation: what to watch for, or how to word the prompt to preserve working cases.
111
+
112
+ ### 5. Handle qualitative-only insights — STILL PRODUCE FIXES
113
+
114
+ Some insights from Stage 3 may be flagged as "unmeasurable." **These still get fixes.** An insight that the agent fabricates data or violates policy is a real problem whether or not we can measure it programmatically. Treat them the same as any other insight:
115
+
116
+ - Run the same triage (validity → already-handled → code-vs-prompt) as every other insight.
117
+ - Include them in the **priority-ranked implementation list** alongside all other fixes. They are NOT second-class.
118
+ - Use the trace evidence from the insight (not the metric) to assess impact and priority. If the insight has strong trace evidence showing clear failures, rank it accordingly.
119
+ - For prioritization: since there is no metric denominator, use confidence = 0.5 and estimate impact from the severity described in the insight evidence.
120
+ - In the fix entry, note that this fix has no programmatic metric for automated before/after comparison, so improvement should be verified via manual trace review or LLM-as-judge after generating new traces.
121
+
122
+ Only relegate an insight to a non-actionable "Monitor Items" section if the triage concludes it should be **discarded** (not valid or not actionable). Being unmeasurable is NOT a reason to skip fixing it.
123
+
124
+ ### 6. Link to metrics
125
+
126
+ For each non-discarded fix, identify which metric(s) from the rubric would move if this fix is implemented. Use the metric IDs from `eval/baseline_metrics.md` (e.g., M1, M2).
127
+
128
+ ### 7. Prioritize
129
+
130
+ Rank non-discarded fixes using this formula:
131
+
132
+ ```
133
+ Priority Score = Impact × Confidence × Tier Bonus ÷ Risk Factor
134
+ ```
135
+
136
+ Where:
137
+ - **Impact** = estimated metric delta. Use the gap between baseline and 100% as the ceiling. A fix expected to close 50% of that gap on M1 (baseline 41.4%) has impact = 0.5 × (1.0 - 0.414) = 0.293.
138
+ - **Confidence** = sample size reliability. Use the denominator from `baseline_metrics.json`:
139
+ - denominator >= 20: confidence = 1.0
140
+ - denominator 10-19: confidence = 0.8
141
+ - denominator 5-9: confidence = 0.6
142
+ - denominator < 5: confidence = 0.3
143
+ - **Tier Bonus** = leading metrics get a 1.5x multiplier (they validate adoption), lagging and quality get 1.0x. Rationale: leading metrics move first and tell you if your fix is even being adopted — you want those signals early.
144
+ - **Risk Factor** = None: 1.0, Low: 1.0, Medium: 1.5, High: 2.0
145
+
146
+ You do not need to compute exact scores to three decimal places. The formula is a tiebreaker and sanity check. The point is:
147
+ - High-impact, high-confidence, leading-metric fixes with low risk go first.
148
+ - Low-confidence fixes (small denominators) get deprioritized even if the metric is at 0%.
149
+ - High-risk fixes get deprioritized unless impact is overwhelming.
150
+
151
+ After scoring, apply one manual adjustment pass: if a fix is a prerequisite for another fix (e.g., "confirmation protocol" must exist before "post-confirmation execution" can be measured), promote the prerequisite even if its standalone score is lower.
152
+
153
+ ## Output format
154
+
155
+ Write to `eval/action_plan.md`:
156
+
157
+ ```markdown
158
+ # Action Plan
159
+
160
+ ## Summary
161
+ - Total insights: N
162
+ - Discarded: X (with reasons)
163
+ - Code fixes: Y
164
+ - Prompt fixes: Z
165
+ - Fixes without programmatic metric (verify manually): Q
166
+
167
+ ## Implementation Priority
168
+ | Rank | Fix | Type | Metrics | Risk | Score rationale |
169
+ |------|-----|------|---------|------|-----------------|
170
+ | 1 | [name] | prompt | M1, M2 | Low | [one-line: why this ranks here] |
171
+ | 2 | ... | ... | ... | ... | ... |
172
+
173
+ ---
174
+
175
+ ## Skill: [insight ID(s)] — [title]
176
+ **Summary:** [one-line description of what the skill addresses]
177
+ **Verdict:** `prompt fix` | `code fix` | `discard`
178
+ **Classification path:** [which branch of the decision tree — e.g., "Agent has tools and data but acts wrong → prompt fix"]
179
+ **Rationale:** [why this verdict — reference specific trace evidence from insights]
180
+ **Risk:** None | Low | Medium | High — [one-sentence justification]
181
+ **Risk mitigation:** [for Medium/High only — what to watch for or how to preserve working cases]
182
+ **Recommendation:** [specific change to make]
183
+ **Files to modify:** [list of files, for code fixes]
184
+ **Metric link:** [which metrics would move, with baseline values]
185
+ **Already-handled check:** [what you grepped, what existing prompt text you found, verdict]
186
+
187
+ ---
188
+ [repeat for each insight]
189
+
190
+ ## Consolidated Prompt Skills
191
+ [After all per-insight entries, list the final merged prompt skill texts in priority order, ready for Stage 7 to implement]
192
+
193
+ ## Monitor Items (Non-Actionable Only)
194
+ [Only insights that were triaged as genuinely non-actionable — e.g., the agent cannot change this behavior, or the insight is noise. Unmeasurable insights that are still real problems should appear in the priority list above, NOT here.]
195
+ ```
196
+
197
+ Group related insights under cluster headings when they address the same underlying behavior. For merged insights, list all constituent insight IDs in the heading.
198
+
199
+ ## Outputs
200
+
201
+ - `eval/action_plan.md`
.claude/skills/kayba-pipeline/stage-6-hitl/SKILL.md ADDED
@@ -0,0 +1,258 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ name: kayba-stage-6-hitl
3
+ description: Human-In-The-Loop gate that presents the action plan with full context, collects an informed approval/modification/rejection decision, and records the outcome. Trigger when the user says "run stage 6", "HITL review", "approve action plan", or when invoked by the kayba-pipeline orchestrator. Requires eval/action_plan.md and eval/baseline_metrics.md to exist.
4
+ ---
5
+
6
+ # Stage 6: Human-In-The-Loop Gate
7
+
8
+ Present the action plan with enough context for an informed decision, collect the user's approval, and record the outcome.
9
+
10
+ The goal is not rubber-stamping. The user must receive enough information to genuinely evaluate, modify, or reject the plan -- even if they have not seen Stages 1-5.
11
+
12
+ ## Inputs
13
+
14
+ - `eval/action_plan.md` -- the prioritized action plan from Stage 5
15
+ - `eval/baseline_metrics.md` -- the evaluation rubric with baseline values
16
+ - `eval/baseline_metrics.json` -- raw metric data (for exact numerator/denominator counts)
17
+ - `eval/stage1_insights_summary.md` -- original insights (for trace evidence references)
18
+
19
+ Read all four files before starting.
20
+
21
+ ## Process
22
+
23
+ ### 1. Build the executive summary
24
+
25
+ Compute and present the following counts from the action plan:
26
+
27
+ - Total insights analyzed (raw count before deduplication)
28
+ - Distinct actionable items after deduplication
29
+ - Breakdown: prompt fixes, code fixes, discarded
30
+ - Discard rate with one-line reason per discard (e.g., "5ac7f4ce: efficiency optimization, conflicts with turn discipline constraint")
31
+
32
+ Format:
33
+
34
+ ```
35
+ EXECUTIVE SUMMARY
36
+ -----------------
37
+ Insights analyzed: 19 (raw) -> 12 distinct after dedup
38
+ Actionable: 9 (8 prompt fixes, 1 code fix)
39
+ Discarded: 3 (reasons listed below)
40
+
41
+ Discards:
42
+ - 5ac7f4ce (Upfront Info Collection): conflicts with higher-priority turn discipline
43
+ - fe2d51cb (Proactive Reservation Lookup): already default behavior, no failure evidence
44
+ - 1fa1b826 (Cancellation Denial Enumeration): subsumed into cancellation checklist
45
+ ```
46
+
47
+ ### 2. Present the top 3 highest-impact changes
48
+
49
+ For each of the top 3 fixes by priority, present:
50
+
51
+ **Before/after behavior** -- use concrete examples from actual traces referenced in the insights. Quote the specific agent behavior that was wrong (before) and describe what the agent should do instead (after). Reference the trace task ID.
52
+
53
+ **Target metric delta** -- which metric(s) this fix targets, the current baseline value, and the expected direction. Do not fabricate precise target numbers. Use the format: "M1: 41.4% -> higher (target: 90%+)" only when the action plan provides a target; otherwise use "M1: 41.4% -> up".
54
+
55
+ **Risk rating** -- assess each fix:
56
+ - `Low` -- additive prompt instruction, no behavioral side effects expected
57
+ - `Medium` -- changes existing behavior, could affect adjacent workflows
58
+ - `High` -- modifies code/infrastructure, or could degrade a metric while improving another
59
+
60
+ Format each as a numbered block:
61
+
62
+ ```
63
+ #1: Turn Discipline (covers 55c00c40, d9683144)
64
+ Type: prompt fix
65
+ Metrics: M1 (41.4% -> up), M2 (20.7% -> up)
66
+ Risk: Low
67
+
68
+ BEFORE (task_1, task_5, task_7, ...):
69
+ Agent batches 2-3 tool calls per turn (e.g., get_reservation + get_flight_status
70
+ in a single response). Also includes user-facing text alongside tool calls.
71
+
72
+ AFTER:
73
+ Exactly one tool call per response. No user-facing content in tool-call turns.
74
+ Agent processes each result before making the next call.
75
+ ```
76
+
77
+ ### 3. Present the full prioritized fix list
78
+
79
+ Display all non-discarded fixes in a table:
80
+
81
+ ```
82
+ | Priority | Fix Name | Type | Target Metrics | Risk | Effort |
83
+ |----------|-----------------------------------|------------|-----------------|--------|--------|
84
+ | 1 | Turn Discipline | prompt fix | M1, M2 | Low | Low |
85
+ | 2 | Post-Confirmation Execution | prompt fix | M3 | Low | Low |
86
+ | 3 | Cancellation Checklist | prompt fix | M5 | Low | Low |
87
+ | ... | ... | ... | ... | ... | ... |
88
+ ```
89
+
90
+ Effort ratings:
91
+ - `Low` -- single prompt addition, under 5 lines
92
+ - `Medium` -- multiple prompt additions or minor code change
93
+ - `High` -- significant code changes, new metric implementation, or architectural changes
94
+
95
+ ### 4. Present "What we are NOT fixing and why"
96
+
97
+ List every discarded insight with:
98
+ - Insight ID and name
99
+ - One-line reason for discard
100
+ - What would change your mind (under what conditions should this be revisited)
101
+
102
+ This section exists so the user can override a discard if they disagree.
103
+
104
+ ### 5. Flag small-sample and low-confidence items
105
+
106
+ Any metric with denominator < 5 must be explicitly called out:
107
+
108
+ ```
109
+ LOW-CONFIDENCE METRICS (small sample size):
110
+ - M5 (Cancellation Policy Compliance): based on 2 observations -- directional only
111
+ - M6 (Compensation Execution Rate): based on 1 observation -- directional only
112
+
113
+ Fixes targeting these metrics (Cancellation Checklist, Compensation Rules) are
114
+ still recommended because the policy violations are clear from trace evidence,
115
+ but the measured improvement may not be statistically meaningful until the
116
+ trace corpus grows.
117
+ ```
118
+
119
+ Also flag any fix where the action plan notes uncertainty or partial evidence.
120
+
121
+ ### 6. Show the insight-to-fix traceability chain
122
+
123
+ For each fix, present the chain: insight -> metric -> fix -> expected improvement. This can be a compact list or a table. The purpose is to let the user verify that nothing was lost or invented between stages.
124
+
125
+ ```
126
+ TRACEABILITY:
127
+ 55c00c40 (Tool Call Discipline) -> M1, M2 -> Skill 1 (Turn Discipline) -> M1 up, M2 up
128
+ 6ea141e1 (Execution Discipline) -> M3 -> Skill 2 (Post-Confirmation) -> M3 up
129
+ 0f4a952b + 6ce88ebb (Cancellation) -> M5 -> Skill 3 (Cancellation Checklist) -> M5 up
130
+ ...
131
+ ```
132
+
133
+ ### 7. Collect the decision
134
+
135
+ Present exactly three options:
136
+
137
+ ```
138
+ OPTIONS:
139
+ [A] Approve all -- implement all 9 fixes as described
140
+ [B] Approve with modifications -- review each fix individually
141
+ [C] Reject -- return to Stage 5 with feedback
142
+ ```
143
+
144
+ Use the appropriate mechanism to collect the user's choice (direct question or AskUserQuestion if available).
145
+
146
+ #### If the user selects [A] Approve all
147
+
148
+ Record the decision and proceed. No further interaction needed.
149
+
150
+ #### If the user selects [B] Approve with modifications
151
+
152
+ Walk through each fix individually, in priority order. For each fix, present:
153
+ - The fix name, type, and target metrics
154
+ - The recommended prompt/code change (quote the exact text from the action plan)
155
+ - Risk and effort ratings
156
+
157
+ Then ask: "Approve / Skip / Modify?"
158
+
159
+ - **Approve** -- keep as-is
160
+ - **Skip** -- remove from the plan, record reason
161
+ - **Modify** -- ask the user what to change, record the original and the modification
162
+
163
+ After walking through all fixes, present a summary of changes:
164
+ - Fixes approved as-is: N
165
+ - Fixes skipped: M (list with reasons)
166
+ - Fixes modified: K (list with what changed)
167
+
168
+ Ask for final confirmation: "Proceed with this modified plan?"
169
+
170
+ Then update `eval/action_plan.md`:
171
+ - Remove skipped fixes (move to a "Skipped by HITL" section at the bottom with reasons)
172
+ - Update modified fixes with the user's changes, preserving the original recommendation in a "Original recommendation" sub-field
173
+ - Add a header note: "Modified during HITL review on [date]. See eval/stage6_decision.md for details."
174
+
175
+ #### If the user selects [C] Reject
176
+
177
+ Ask the user for specific feedback:
178
+ - What was wrong with the plan?
179
+ - Which insights or metrics should be reconsidered?
180
+ - Any new constraints or priorities?
181
+
182
+ Record the feedback in `eval/stage6_decision.md` and signal that Stage 5 should be re-run with the user's feedback incorporated.
183
+
184
+ ## Output format
185
+
186
+ ### eval/stage6_decision.md
187
+
188
+ Write this file regardless of which option was selected.
189
+
190
+ ```markdown
191
+ # Stage 6: HITL Decision Record
192
+
193
+ ## Date
194
+ [timestamp]
195
+
196
+ ## Decision
197
+ [Approve all | Approve with modifications | Reject]
198
+
199
+ ## What was presented
200
+ - Total insights: N (M distinct after dedup)
201
+ - Actionable fixes: X (Y prompt, Z code)
202
+ - Discarded: W
203
+ - Metrics: [list metric IDs and baselines]
204
+ - Low-confidence flags: [list metrics with small denominators]
205
+
206
+ ## Top 3 changes presented
207
+ 1. [fix name] -- [type] -- targets [metrics] -- risk [rating]
208
+ 2. ...
209
+ 3. ...
210
+
211
+ ## Decision details
212
+
213
+ ### If Approve all:
214
+ User approved all N fixes without modification.
215
+ Reasoning: [any reasoning the user provided, or "No additional reasoning provided"]
216
+
217
+ ### If Approve with modifications:
218
+ | Fix | Original Status | Decision | Reason |
219
+ |-----|----------------|----------|--------|
220
+ | Turn Discipline | Priority 1 | Approved | -- |
221
+ | Compensation Rules | Priority 5 | Modified | User changed wording to... |
222
+ | Cabin Change Rules | Priority 8 | Skipped | User considers low priority |
223
+
224
+ Modifications detail:
225
+ - [Fix name]: Original: "..." -> Modified: "..." -- User rationale: "..."
226
+
227
+ ### If Reject:
228
+ User feedback: [verbatim feedback]
229
+ Specific concerns: [list]
230
+ Re-run instructions for Stage 5: [what to change]
231
+
232
+ ## Traceability snapshot
233
+ [Copy of the traceability chain from step 6, so the decision record is self-contained]
234
+ ```
235
+
236
+ ### eval/action_plan.md (updated, only if modifications were made)
237
+
238
+ If the user selected [B] and made changes:
239
+ - Add a modification header at the top of the file
240
+ - Update individual fix entries with user changes
241
+ - Move skipped fixes to a "Skipped by HITL" section
242
+ - Preserve original recommendations as sub-fields for auditability
243
+
244
+ ## Rules
245
+
246
+ - Do NOT auto-approve. The entire point of this stage is human judgment.
247
+ - Do NOT summarize so aggressively that the user cannot evaluate. When in doubt, include more context.
248
+ - Do NOT proceed to Stage 7 until a clear approval (full or modified) is recorded.
249
+ - Do NOT modify `eval/action_plan.md` unless the user explicitly requests modifications.
250
+ - Do NOT skip the small-sample warnings. If M5 has denominator 2 and M6 has denominator 1, the user must know this.
251
+ - Do NOT fabricate target metric values. Use targets from the action plan when available; otherwise state direction only.
252
+ - Always present the "What we are NOT fixing" section. Omitting discards hides information the user needs.
253
+ - If the user asks clarifying questions, answer them fully before re-presenting the decision options.
254
+
255
+ ## Outputs
256
+
257
+ - `eval/stage6_decision.md` -- full record of what was presented, decided, and why
258
+ - `eval/action_plan.md` -- updated only if the user selected "Approve with modifications"
.claude/skills/kayba-pipeline/stage-7-fixer/SKILL.md ADDED
@@ -0,0 +1,191 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ name: kayba-stage-7-fixer
3
+ description: Implement the approved fixes from the action plan and log all changes. Trigger when the user says "run stage 7", "implement fixes", "apply action plan", or when invoked by the kayba-pipeline orchestrator. Requires eval/action_plan.md to exist.
4
+ ---
5
+
6
+ # Stage 7: Fix Implementation
7
+
8
+ Implement every non-discarded fix from the approved action plan.
9
+
10
+ ## Inputs
11
+
12
+ - `eval/action_plan.md` -- the approved action plan from Stage 5 (possibly modified during HITL in Stage 6)
13
+ - `eval/stage6_decision.md` -- if it exists, the HITL decision record from Stage 6 (contains user modifications)
14
+ - `eval/baseline_metrics.json` -- the pre-fix baseline metrics from Stage 3 (for reference in changes log)
15
+
16
+ Read the action plan and stage6 decision (if present) before starting.
17
+
18
+ ## Pre-flight: Git Safety Checkpoint
19
+
20
+ Before making ANY changes to source files:
21
+
22
+ 1. Run `git status` to confirm the working tree state
23
+ 2. Create a safety commit or stash:
24
+ ```
25
+ git stash push -m "pre-pipeline-fixes-$(date +%Y%m%d-%H%M%S)"
26
+ ```
27
+ If there are no uncommitted changes to stash, create a lightweight tag instead:
28
+ ```
29
+ git tag pre-pipeline-fixes-$(date +%Y%m%d-%H%M%S)
30
+ ```
31
+ 3. Record the stash ref or tag name in `eval/changes_log.md` under a "Rollback" section so the user can restore if needed
32
+
33
+ This ensures every fix is reversible with a single `git stash pop` or `git checkout`.
34
+
35
+ ## Pre-flight: HITL Modification Check
36
+
37
+ If `eval/stage6_decision.md` exists:
38
+
39
+ 1. Read it and identify any items the user modified, added, or re-prioritized during Stage 6
40
+ 2. Build a set of `HITL_MODIFIED_IDS` -- the insight/skill IDs that the user changed
41
+ 3. When logging each fix later, tag modified items with `[HITL-MODIFIED]` in the changes log so reviewers know which fixes reflect user judgment vs. the original pipeline output
42
+
43
+ If the file does not exist, assume no HITL modifications were made.
44
+
45
+ ## Pre-flight: Conflict Scan
46
+
47
+ Before implementing any fixes, scan the action plan for potential conflicts:
48
+
49
+ 1. Build a map of `file_path -> [fix IDs that touch it]`
50
+ 2. If two or more fixes modify the same file, flag them as **co-located**
51
+ 3. If two or more fixes modify the same section (within ~20 lines of each other), flag them as **overlapping**
52
+ 4. For overlapping fixes: plan to apply them sequentially in priority order, re-reading the file between each edit to ensure the second fix still makes sense on top of the first
53
+ 5. Log any detected conflicts at the top of `eval/changes_log.md` under a "Conflict Notes" section
54
+
55
+ ## Process
56
+
57
+ Work through the action plan in priority order. For each non-discarded fix:
58
+
59
+ ### 1. Understand the fix
60
+
61
+ - Read the recommendation carefully
62
+ - Read the referenced files in the codebase
63
+ - Understand the surrounding code before making changes
64
+ - Check if this fix was flagged as co-located or overlapping in the conflict scan. If overlapping with a previously-applied fix, re-read the target file to see the current state after prior edits
65
+
66
+ ### 2. Implement the change
67
+
68
+ **For code fixes:**
69
+ - Find the relevant files
70
+ - Make the minimal, targeted change described in the recommendation
71
+ - Do not refactor surrounding code unless the fix obviously breaks without light adjacent cleanup (e.g., an import is missing, a variable was renamed). If you make adjacent cleanup, log it explicitly as "adjacent cleanup" in the change entry
72
+ - Do not add features beyond what was recommended
73
+
74
+ **For prompt fixes:**
75
+ - Find the system prompt file (use domain context from Stage 2 if needed)
76
+ - Add the recommended instruction at the appropriate location
77
+ - Do not rewrite existing prompt text unless the recommendation explicitly says to
78
+
79
+ ### 3. Log the change
80
+
81
+ Append to `eval/changes_log.md`:
82
+
83
+ ```markdown
84
+ ## Fix N: [skill/insight name] [HITL-MODIFIED if applicable]
85
+ **Type:** code fix | prompt fix
86
+ **Verdict from action plan:** [quote the recommendation]
87
+ **Files modified:**
88
+ - `path/to/file.py` -- [what changed and why]
89
+ **Before:**
90
+ \```
91
+ [relevant snippet before change]
92
+ \```
93
+ **After:**
94
+ \```
95
+ [relevant snippet after change]
96
+ \```
97
+ **Linked metrics:** [which metrics this should improve]
98
+ **Conflict notes:** [if this fix overlapped with another, note it here; otherwise "none"]
99
+ ```
100
+
101
+ ### 4. Handle uncertainty (NEEDS REVIEW workflow)
102
+
103
+ If a fix requires changes you are unsure about:
104
+
105
+ 1. Do NOT implement it
106
+ 2. Log it as `NEEDS REVIEW` in the changes log with:
107
+ - What specifically is unclear
108
+ - What information would resolve the ambiguity
109
+ - The files and lines you examined
110
+ 3. **Continue to the next fix** -- do not block the pipeline
111
+ 4. At the end of all fixes, collect all NEEDS REVIEW items into a dedicated section (see Output format below). The pipeline does NOT stop; these items are presented to the user after all other fixes are applied.
112
+
113
+ ## Post-Fix: Next Steps (Do NOT Re-run Baselines)
114
+
115
+ Do NOT re-run `compute_baselines.py` as part of this stage. The baseline metrics were computed against the original traces, which reflect old agent behavior. Re-running against the same traces will show zero movement for prompt-only fixes and is misleading.
116
+
117
+ Instead, after all fixes are applied, include a **Next Steps** section in the changes log that tells the user:
118
+
119
+ 1. Generate new traces by running the agent with the updated prompts/code
120
+ 2. Then re-run baselines against the new traces:
121
+ ```bash
122
+ python eval/compute_baselines.py --traces-dir <new_traces_folder> --output eval/post_fix_metrics.json
123
+ ```
124
+ 3. Compare `eval/post_fix_metrics.json` against `eval/baseline_metrics.json` to measure actual improvement
125
+
126
+ ## Rules
127
+
128
+ - Do NOT modify trace files
129
+ - Do NOT make changes beyond what the action plan recommends (except adjacent cleanup logged explicitly)
130
+ - Make minimal, targeted changes -- don't clean up or refactor surrounding code
131
+ - If the action plan says "discard", skip that entry entirely
132
+ - You MAY write `eval/changes_log.md` as the primary output
133
+ - Do NOT run `eval/compute_baselines.py` -- baselines should only be re-computed after new traces are generated with the updated agent
134
+
135
+ ## Output format
136
+
137
+ Write `eval/changes_log.md`:
138
+
139
+ ```markdown
140
+ # Changes Log
141
+
142
+ ## Rollback
143
+ - **Safety ref:** `git stash` ref or tag name
144
+ - **To undo all fixes:** `git stash pop` or `git checkout <tag>`
145
+
146
+ ## Conflict Notes
147
+ - [any file/region conflicts detected, or "No conflicts detected"]
148
+
149
+ ## Summary
150
+ - Code fixes applied: N
151
+ - Prompt fixes applied: M
152
+ - Skipped / needs review: K
153
+ - HITL-modified items: J
154
+
155
+ ---
156
+
157
+ ## Fix 1: [skill name]
158
+ ...
159
+
160
+ ## Fix 2: [skill name]
161
+ ...
162
+
163
+ ---
164
+
165
+ ## Needs Review
166
+ [Collected list of all NEEDS REVIEW items with context, or "None -- all fixes applied successfully"]
167
+
168
+ For each NEEDS REVIEW item:
169
+ - **Fix N: [skill name]**
170
+ - **What is unclear:** [specific ambiguity]
171
+ - **What would resolve it:** [information needed]
172
+ - **Files examined:** [paths and lines]
173
+
174
+ ---
175
+
176
+ ## Next Steps
177
+
178
+ To measure actual improvement:
179
+ 1. Generate new traces by running the agent with the updated prompts/code
180
+ 2. Re-run baselines:
181
+ \```bash
182
+ python eval/compute_baselines.py --traces-dir <new_traces_folder> --output eval/post_fix_metrics.json
183
+ \```
184
+ 3. Compare `eval/post_fix_metrics.json` against `eval/baseline_metrics.json` to measure metric deltas
185
+ ```
186
+
187
+ ## Outputs
188
+
189
+ - `eval/changes_log.md` -- full log of all changes, conflicts, NEEDS REVIEW items, and next steps
190
+ - The actual code/prompt changes in the repository
191
+ - A git stash or tag for rollback
.env.example ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # API Keys for LLM Providers
2
+ # Copy this file to .env and add your actual API keys
3
+
4
+ # OpenAI
5
+ OPENAI_API_KEY=your-openai-api-key-here
6
+
7
+ # Anthropic (Claude)
8
+ ANTHROPIC_API_KEY=your-anthropic-api-key-here
9
+
10
+ # Google (Gemini)
11
+ GOOGLE_API_KEY=your-google-api-key-here
12
+
13
+ # DeepSeek
14
+ DEEPSEEK_API_KEY=your-deepseek-api-key-here
15
+
16
+ # Ollama Cloud
17
+ OLLAMA_API_KEY=your_api_key
18
+
19
+ # Cohere
20
+ COHERE_API_KEY=your-cohere-api-key-here
21
+
22
+ # Bedrock bearer token (passed as api_key to LiteLLM, not as AWS_ACCESS_KEY_ID)
23
+ BEDROCK_API_KEY=your-bedrock-api-key-here
24
+
25
+ # Azure OpenAI (optional)
26
+ AZURE_API_KEY=your-azure-api-key-here
27
+ AZURE_API_BASE=https://your-resource.openai.azure.com
28
+ AZURE_API_VERSION=2024-02-15-preview
29
+
30
+ # AWS Bedrock (optional)
31
+ AWS_ACCESS_KEY_ID=your-aws-access-key
32
+ AWS_SECRET_ACCESS_KEY=your-aws-secret-key
33
+ AWS_REGION_NAME=us-east-1
34
+
35
+ # Hugging Face (optional)
36
+ HUGGINGFACE_API_KEY=your-huggingface-api-key-here
37
+
38
+ # Replicate (optional)
39
+ REPLICATE_API_KEY=your-replicate-api-key-here
40
+
41
+ # Together AI (optional)
42
+ TOGETHER_API_KEY=your-together-api-key-here
43
+
44
+ # Model Configuration (optional)
45
+ DEFAULT_MODEL=gpt-4o-mini
46
+ DEFAULT_TEMPERATURE=0.0
47
+ DEFAULT_MAX_TOKENS=512
48
+
49
+ # Cost Tracking (optional)
50
+ TRACK_COSTS=true
51
+ MAX_BUDGET=10.0
52
+
53
+ # Opik Observability (optional)
54
+ # Disable Opik tracing when not running a local Opik server
55
+ # Either variable works:
56
+ # OPIK_ENABLED=false
57
+ # OPIK_DISABLED=true
58
+
59
+ # Benchmark Configuration
60
+ # Cache directories for benchmark data (optional - defaults to ~/.cache/huggingface)
61
+ BENCHMARK_CACHE_DIR=/path/to/benchmark/cache
62
+ HF_DATASETS_CACHE=/path/to/huggingface/cache
63
+ HF_HUB_CACHE=/path/to/huggingface/hub/cache
64
+
65
+ # AppWorld configuration (required for AppWorld benchmark)
66
+ APPWORLD_ROOT=/path/to/appworld/data
67
+
68
+ # Results output directory (optional)
69
+ BENCHMARK_RESULTS_DIR=./benchmark_results
.gitattributes CHANGED
@@ -33,3 +33,7 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ assets/kayba-banner.png filter=lfs diff=lfs merge=lfs -text
37
+ benchmarks/tasks/tau_bench/Tau2Benchmark[[:space:]]Result[[:space:]]Haiku4.5.png filter=lfs diff=lfs merge=lfs -text
38
+ examples/seahorse-emoji-ace.gif filter=lfs diff=lfs merge=lfs -text
39
+ mlflow.db filter=lfs diff=lfs merge=lfs -text
.github/workflows/docs.yml ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Docs
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ tags:
8
+ - "v*"
9
+ workflow_dispatch:
10
+ inputs:
11
+ version:
12
+ description: "Version to deploy (e.g. 0.8)"
13
+ required: true
14
+ default: "dev"
15
+
16
+ permissions:
17
+ contents: write
18
+
19
+ jobs:
20
+ deploy:
21
+ runs-on: ubuntu-latest
22
+ steps:
23
+ - uses: actions/checkout@v4
24
+ with:
25
+ fetch-depth: 0 # Required for mike versioning
26
+
27
+ - name: Set up Python
28
+ uses: actions/setup-python@v5
29
+ with:
30
+ python-version: "3.12"
31
+
32
+ - name: Install docs dependencies
33
+ run: pip install mkdocs-material mike
34
+
35
+ - name: Configure git
36
+ run: |
37
+ git config user.name "github-actions[bot]"
38
+ git config user.email "github-actions[bot]@users.noreply.github.com"
39
+
40
+ - name: Deploy versioned docs (on tag)
41
+ if: startsWith(github.ref, 'refs/tags/v')
42
+ run: |
43
+ VERSION=${GITHUB_REF#refs/tags/v}
44
+ mike deploy --push --update-aliases $VERSION latest
45
+ mike set-default --push latest
46
+
47
+ - name: Deploy dev docs (on main push)
48
+ if: github.ref == 'refs/heads/main'
49
+ run: mike deploy --push dev
50
+
51
+ - name: Deploy manually triggered version
52
+ if: github.event_name == 'workflow_dispatch'
53
+ run: |
54
+ mike deploy --push --update-aliases ${{ github.event.inputs.version }} latest
55
+ mike set-default --push latest
.github/workflows/publish.yml ADDED
@@ -0,0 +1,290 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Publish Packages
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+ workflow_dispatch:
7
+ inputs:
8
+ test_pypi:
9
+ description: 'Publish to TestPyPI instead of PyPI'
10
+ required: false
11
+ default: 'false'
12
+ type: choice
13
+ options:
14
+ - 'true'
15
+ - 'false'
16
+
17
+ jobs:
18
+ # ── ace-framework (Python) ──────────────────────────────────────────
19
+
20
+ build-ace:
21
+ name: Build ace-framework
22
+ runs-on: ubuntu-latest
23
+ steps:
24
+ - uses: actions/checkout@v4
25
+
26
+ - name: Set up Python
27
+ uses: actions/setup-python@v4
28
+ with:
29
+ python-version: '3.12'
30
+
31
+ - name: Install build dependencies
32
+ run: |
33
+ python -m pip install --upgrade pip
34
+ pip install build
35
+
36
+ - name: Build package
37
+ run: python -m build
38
+
39
+ - name: Store the distribution packages
40
+ uses: actions/upload-artifact@v4
41
+ with:
42
+ name: ace-framework-dist
43
+ path: dist/
44
+
45
+ # ── kayba-tracing (Python) ─────────────────────────────────────────
46
+
47
+ build-kayba-tracing:
48
+ name: Build kayba-tracing
49
+ runs-on: ubuntu-latest
50
+ steps:
51
+ - uses: actions/checkout@v4
52
+
53
+ - name: Set up Python
54
+ uses: actions/setup-python@v4
55
+ with:
56
+ python-version: '3.12'
57
+
58
+ - name: Install build dependencies
59
+ run: |
60
+ python -m pip install --upgrade pip
61
+ pip install build
62
+
63
+ - name: Build package
64
+ run: python -m build sdk/python
65
+
66
+ - name: Store the distribution packages
67
+ uses: actions/upload-artifact@v4
68
+ with:
69
+ name: kayba-tracing-dist
70
+ path: sdk/python/dist/
71
+
72
+ # ── @kayba_ai/tracing (TypeScript) ────────────────────────────────────
73
+
74
+ build-kayba-tracing-ts:
75
+ name: Build @kayba_ai/tracing
76
+ runs-on: ubuntu-latest
77
+ steps:
78
+ - uses: actions/checkout@v4
79
+
80
+ - name: Set up Node.js
81
+ uses: actions/setup-node@v4
82
+ with:
83
+ node-version: '20'
84
+ registry-url: 'https://registry.npmjs.org'
85
+
86
+ - name: Install dependencies
87
+ run: npm ci
88
+ working-directory: sdk/typescript
89
+
90
+ - name: Build
91
+ run: npm run build
92
+ working-directory: sdk/typescript
93
+
94
+ - name: Store the distribution packages
95
+ uses: actions/upload-artifact@v4
96
+ with:
97
+ name: kayba-tracing-ts-dist
98
+ path: |
99
+ sdk/typescript/dist/
100
+ sdk/typescript/package.json
101
+
102
+ # ── @kayba_ai/openclaw-tracing (TypeScript) ───────────────────────────
103
+
104
+ build-openclaw-tracing:
105
+ name: Build @kayba_ai/openclaw-tracing
106
+ runs-on: ubuntu-latest
107
+ steps:
108
+ - uses: actions/checkout@v4
109
+
110
+ - name: Set up Node.js
111
+ uses: actions/setup-node@v4
112
+ with:
113
+ node-version: '22'
114
+ registry-url: 'https://registry.npmjs.org'
115
+
116
+ - name: Install dependencies
117
+ run: npm ci
118
+ working-directory: sdk/openclaw
119
+
120
+ - name: Build
121
+ run: npm run build
122
+ working-directory: sdk/openclaw
123
+
124
+ - name: Store the distribution packages
125
+ uses: actions/upload-artifact@v4
126
+ with:
127
+ name: openclaw-tracing-dist
128
+ path: |
129
+ sdk/openclaw/dist/
130
+ sdk/openclaw/package.json
131
+ sdk/openclaw/openclaw.plugin.json
132
+ sdk/openclaw/README.md
133
+
134
+ # ── Publish to TestPyPI ────────────────────────────────────────────
135
+
136
+ publish-to-testpypi:
137
+ name: Publish ace-framework to TestPyPI
138
+ if: github.event.inputs.test_pypi == 'true' || github.event_name == 'workflow_dispatch'
139
+ needs: [build-ace]
140
+ runs-on: ubuntu-latest
141
+ environment:
142
+ name: testpypi
143
+ url: https://test.pypi.org/project/ace-framework/
144
+ permissions:
145
+ id-token: write
146
+ steps:
147
+ - name: Download all the dists
148
+ uses: actions/download-artifact@v4
149
+ with:
150
+ name: ace-framework-dist
151
+ path: dist/
152
+
153
+ - name: Publish to TestPyPI
154
+ uses: pypa/gh-action-pypi-publish@release/v1
155
+ with:
156
+ repository-url: https://test.pypi.org/legacy/
157
+ skip-existing: true
158
+
159
+ publish-kayba-tracing-to-testpypi:
160
+ name: Publish kayba-tracing to TestPyPI
161
+ if: github.event.inputs.test_pypi == 'true' || github.event_name == 'workflow_dispatch'
162
+ needs: [build-kayba-tracing]
163
+ runs-on: ubuntu-latest
164
+ environment:
165
+ name: testpypi
166
+ url: https://test.pypi.org/project/kayba-tracing/
167
+ permissions:
168
+ id-token: write
169
+ steps:
170
+ - name: Download all the dists
171
+ uses: actions/download-artifact@v4
172
+ with:
173
+ name: kayba-tracing-dist
174
+ path: dist/
175
+
176
+ - name: Publish to TestPyPI
177
+ uses: pypa/gh-action-pypi-publish@release/v1
178
+ with:
179
+ repository-url: https://test.pypi.org/legacy/
180
+ skip-existing: true
181
+
182
+ # ── Publish to PyPI ────────────────────────────────────────────────
183
+
184
+ publish-to-pypi:
185
+ name: Publish ace-framework to PyPI
186
+ if: github.event_name == 'release'
187
+ needs: [build-ace]
188
+ runs-on: ubuntu-latest
189
+ environment:
190
+ name: pypi
191
+ url: https://pypi.org/project/ace-framework/
192
+ permissions:
193
+ id-token: write
194
+ steps:
195
+ - name: Download all the dists
196
+ uses: actions/download-artifact@v4
197
+ with:
198
+ name: ace-framework-dist
199
+ path: dist/
200
+
201
+ - name: Publish to PyPI
202
+ uses: pypa/gh-action-pypi-publish@release/v1
203
+
204
+ publish-kayba-tracing-to-pypi:
205
+ name: Publish kayba-tracing to PyPI
206
+ if: github.event_name == 'release'
207
+ needs: [build-kayba-tracing]
208
+ runs-on: ubuntu-latest
209
+ environment:
210
+ name: pypi
211
+ url: https://pypi.org/project/kayba-tracing/
212
+ permissions:
213
+ id-token: write
214
+ steps:
215
+ - name: Download all the dists
216
+ uses: actions/download-artifact@v4
217
+ with:
218
+ name: kayba-tracing-dist
219
+ path: dist/
220
+
221
+ - name: Publish to PyPI
222
+ uses: pypa/gh-action-pypi-publish@release/v1
223
+
224
+ # ── Publish to npm ─────────────────────────────────────────────────
225
+
226
+ publish-to-npm:
227
+ name: Publish @kayba_ai/tracing to npm
228
+ if: github.event_name == 'release'
229
+ needs: [build-kayba-tracing-ts]
230
+ runs-on: ubuntu-latest
231
+ environment:
232
+ name: npm
233
+ url: https://www.npmjs.com/package/@kayba_ai/tracing
234
+ permissions:
235
+ contents: read
236
+ steps:
237
+ - uses: actions/checkout@v4
238
+
239
+ - name: Set up Node.js
240
+ uses: actions/setup-node@v4
241
+ with:
242
+ node-version: '22'
243
+ registry-url: 'https://registry.npmjs.org'
244
+
245
+ - name: Install dependencies
246
+ run: npm ci
247
+ working-directory: sdk/typescript
248
+
249
+ - name: Build
250
+ run: npm run build
251
+ working-directory: sdk/typescript
252
+
253
+ - name: Publish to npm
254
+ run: npm publish --access public
255
+ working-directory: sdk/typescript
256
+ env:
257
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
258
+
259
+ publish-openclaw-tracing-to-npm:
260
+ name: Publish @kayba_ai/openclaw-tracing to npm
261
+ if: github.event_name == 'release'
262
+ needs: [build-openclaw-tracing]
263
+ runs-on: ubuntu-latest
264
+ environment:
265
+ name: npm
266
+ url: https://www.npmjs.com/package/@kayba_ai/openclaw-tracing
267
+ permissions:
268
+ contents: read
269
+ steps:
270
+ - uses: actions/checkout@v4
271
+
272
+ - name: Set up Node.js
273
+ uses: actions/setup-node@v4
274
+ with:
275
+ node-version: '22'
276
+ registry-url: 'https://registry.npmjs.org'
277
+
278
+ - name: Install dependencies
279
+ run: npm ci
280
+ working-directory: sdk/openclaw
281
+
282
+ - name: Build
283
+ run: npm run build
284
+ working-directory: sdk/openclaw
285
+
286
+ - name: Publish to npm
287
+ run: npm publish --access public
288
+ working-directory: sdk/openclaw
289
+ env:
290
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
.github/workflows/test.yml ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Tests
2
+
3
+ on:
4
+ push:
5
+ branches: [ main, develop, lanzelot-dev ]
6
+ pull_request:
7
+ branches: [ main ]
8
+ workflow_dispatch: # Allow manual triggering
9
+
10
+ jobs:
11
+ test:
12
+ runs-on: ${{ matrix.os }}
13
+ strategy:
14
+ matrix:
15
+ os: [ubuntu-latest, windows-latest, macos-latest]
16
+ python-version: ['3.12'] # Matches pyproject.toml requires-python == 3.12.*
17
+
18
+ steps:
19
+ - uses: actions/checkout@v4
20
+
21
+ - name: Set up Python ${{ matrix.python-version }}
22
+ uses: actions/setup-python@v4
23
+ with:
24
+ python-version: ${{ matrix.python-version }}
25
+
26
+ - name: Install uv
27
+ uses: astral-sh/setup-uv@v7
28
+
29
+ - name: Install dependencies
30
+ run: uv sync --extra mcp --extra tracing
31
+
32
+ - name: Run tests with coverage
33
+ run: |
34
+ uv run pytest -m "not requires_api"
35
+
36
+ - name: Upload coverage reports (Linux only)
37
+ if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.12'
38
+ uses: actions/upload-artifact@v4
39
+ with:
40
+ name: coverage-report
41
+ path: htmlcov/
42
+ retention-days: 30
43
+
44
+ - name: Type checking (Linux only)
45
+ if: matrix.os == 'ubuntu-latest'
46
+ run: |
47
+ uv run mypy ace/ --ignore-missing-imports
.gitignore ADDED
@@ -0,0 +1,124 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ *.egg-info/
24
+ .installed.cfg
25
+ *.egg
26
+
27
+ # PyInstaller
28
+ *.manifest
29
+ *.spec
30
+
31
+ # Installer logs
32
+ pip-log.txt
33
+ pip-delete-this-directory.txt
34
+
35
+ # Unit test / coverage reports
36
+ htmlcov/
37
+ .tox/
38
+ .coverage
39
+ .coverage.*
40
+ .cache
41
+ nosetests.xml
42
+ coverage.xml
43
+ *.cover
44
+ .hypothesis/
45
+ .pytest_cache/
46
+
47
+ # Jupyter Notebook
48
+ .ipynb_checkpoints
49
+
50
+ # pyenv
51
+ .python-version
52
+
53
+ # Environments
54
+ .env
55
+ .venv
56
+ env/
57
+ venv/
58
+ ENV/
59
+ env.bak/
60
+ venv.bak/
61
+
62
+ # IDE
63
+ .idea/
64
+ .vscode/
65
+ *.swp
66
+ *.swo
67
+ *~
68
+ .DS_Store
69
+
70
+ # Project specific
71
+ *.pdf
72
+ *.png
73
+ !benchmarks/tasks/tau_bench/*.png
74
+ !examples/browser-use/**/*.png
75
+ !assets/*.png
76
+ ACE_IMPROVEMENTS.md
77
+ ACE_ROADMAP.md
78
+ DEMO_TODO.md
79
+ *.egg-info/
80
+ reports/
81
+ docs/method_outline.md
82
+ logs/
83
+
84
+ # Generated skillbook and result files
85
+ *_skillbook.json
86
+ ace_domain_skillbook.json
87
+ kayba_learned.json
88
+ kayba_test_skillbook.json
89
+ my_agent.json
90
+ my_trained_agent.json
91
+ *.log
92
+
93
+ # Checkpoint files (generated during training)
94
+ **/checkpoints/*.json
95
+ *_checkpoint_*.json
96
+ *_latest.json
97
+ evaluation_results/*.json
98
+
99
+ # Benchmark data and cache
100
+ benchmark_results/
101
+ benchmark_cache/
102
+ tau_benchmark_results/
103
+ results/
104
+ appworld_data/
105
+ *.arrow
106
+ *.parquet
107
+ huggingface_cache/
108
+
109
+ # MkDocs build output
110
+ site/
111
+
112
+ # Sensitive/private data (NEVER commit!)
113
+ .private/
114
+
115
+ # GSD planning artifacts (NEVER commit!)
116
+ .planning/
117
+
118
+ # Node build artifacts
119
+ node_modules/
120
+
121
+ # Local scratch / experiment outputs
122
+ tmp/
123
+
124
+ spyfly-traces
.gitmodules ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ [submodule "ace-eval"]
2
+ path = ace-eval
3
+ url = git@github.com:kayba-ai/ace-eval.git
.pre-commit-config.yaml ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ repos:
2
+ # Black - code formatting (auto-fixes)
3
+ - repo: https://github.com/psf/black
4
+ rev: 24.10.0
5
+ hooks:
6
+ - id: black
7
+ args: [--line-length=88]
8
+ language_version: python3.12
9
+
10
+ # MyPy - type checking (blocks commits on errors)
11
+ - repo: https://github.com/pre-commit/mirrors-mypy
12
+ rev: v1.11.2
13
+ hooks:
14
+ - id: mypy
15
+ args: [--ignore-missing-imports, --warn-unused-configs]
16
+ additional_dependencies:
17
+ - types-requests
18
+ - types-pyyaml
19
+ files: ^ace/
20
+ language_version: python3.12
.specify/memory/constitution.md ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!--
2
+ Sync Impact Report
3
+ ==================
4
+ Version change: 1.0.0 → 1.1.0
5
+ Principles added:
6
+ - IV. Clean & Modular Code
7
+ Principles unchanged:
8
+ - I. Ease of Use First
9
+ - II. Practical Value
10
+ - III. Simplicity
11
+ Sections unchanged:
12
+ - Development Standards
13
+ - Quality Gates
14
+ - Governance
15
+ Removed sections: None
16
+ Templates validated:
17
+ ✅ .specify/templates/plan-template.md — Constitution Check section compatible
18
+ ✅ .specify/templates/spec-template.md — No conflicts
19
+ ✅ .specify/templates/tasks-template.md — No conflicts
20
+ ✅ .specify/templates/checklist-template.md — No conflicts
21
+ Follow-up TODOs: None
22
+ -->
23
+
24
+ # ACE Framework Constitution
25
+
26
+ ## Core Principles
27
+
28
+ ### I. Ease of Use First
29
+
30
+ Every public API, integration, and workflow MUST prioritize developer
31
+ experience above all else.
32
+
33
+ - New users MUST be able to install and run a working example in under
34
+ 5 minutes with no more than 3 lines of code.
35
+ - Sensible defaults MUST be provided for every configuration option.
36
+ Users MUST NOT be required to understand internals to get started.
37
+ - Breaking changes to the public API MUST follow deprecation warnings
38
+ for at least one minor release before removal.
39
+ - Documentation MUST include a copy-pasteable quick start for every
40
+ integration (LiteLLM, LangChain, browser-use, Claude Code).
41
+
42
+ ### II. Practical Value
43
+
44
+ Every feature MUST solve a real, demonstrable problem for users
45
+ building AI agents.
46
+
47
+ - Features MUST NOT be added speculatively. Each addition MUST have a
48
+ concrete use case tied to agent improvement or developer workflow.
49
+ - Performance claims MUST be backed by reproducible benchmarks or
50
+ examples. No unsubstantiated marketing language in docs or code.
51
+ - Integration wrappers MUST add measurable value (learning, skillbook
52
+ evolution) beyond what the wrapped framework already provides.
53
+
54
+ ### III. Simplicity
55
+
56
+ Prefer the simplest solution that works. Complexity MUST be justified.
57
+
58
+ - YAGNI: Do not build for hypothetical future requirements. Three
59
+ similar lines of code are better than a premature abstraction.
60
+ - New abstractions MUST be used in at least two places before
61
+ extraction into a shared utility.
62
+ - Dependencies MUST be kept minimal. Optional extras (observability,
63
+ LangChain, transformers) stay optional — the core install MUST
64
+ remain lightweight.
65
+
66
+ ### IV. Clean & Modular Code
67
+
68
+ All code MUST be clean, modular, and extensible.
69
+
70
+ - Modules MUST have a single, clear responsibility. Each file MUST
71
+ do one thing well and expose a well-defined interface.
72
+ - Public APIs MUST be designed for extension without modification.
73
+ New integrations, LLM providers, and adapters MUST be addable
74
+ without changing existing code (open/closed principle).
75
+ - Internal boundaries MUST be respected: core library (`ace/`),
76
+ integrations (`ace/integrations/`), LLM providers
77
+ (`ace/llm_providers/`), and observability (`ace/observability/`)
78
+ MUST NOT have circular dependencies.
79
+ - Functions and classes MUST be small enough to understand at a
80
+ glance. If a function requires scrolling, it MUST be decomposed.
81
+
82
+ ## Development Standards
83
+
84
+ - **Language**: Python 3.12 with type hints on all public APIs.
85
+ - **Formatting**: Black (line length 88). All code MUST pass
86
+ `black --check` before merge.
87
+ - **Testing**: pytest with coverage enforcement (`--cov-fail-under=25`).
88
+ New features MUST include tests. Bug fixes MUST include regression
89
+ tests.
90
+ - **Distribution**: PyPI package `ace-framework`. Core install MUST NOT
91
+ exceed ~150MB. Heavy dependencies belong in optional extras.
92
+ - **Commit style**: Conventional Commits (`feat(scope): subject`).
93
+
94
+ ## Quality Gates
95
+
96
+ - All PRs MUST pass CI (formatting, type checks, test suite) before
97
+ merge.
98
+ - Public API changes MUST update relevant documentation (README,
99
+ docstrings, quick start guides).
100
+ - Benchmark results MUST NOT regress without explicit justification in
101
+ the PR description.
102
+ - Skillbook format changes MUST maintain backward compatibility with
103
+ existing saved skillbooks or provide a migration path.
104
+
105
+ ## Governance
106
+
107
+ This constitution is the highest-authority document for the ACE
108
+ Framework project. All design decisions, PRs, and code reviews MUST
109
+ verify compliance with these principles.
110
+
111
+ - **Amendments**: Any change to this constitution MUST be documented
112
+ with a version bump, rationale, and updated `LAST_AMENDED_DATE`.
113
+ - **Versioning**: MAJOR for principle removals or redefinitions, MINOR
114
+ for new principles or material expansions, PATCH for clarifications.
115
+ - **Compliance**: Use `CLAUDE.md` for runtime development guidance.
116
+ This constitution defines the non-negotiable rules that `CLAUDE.md`
117
+ guidance MUST NOT contradict.
118
+ - **Review**: Constitution compliance SHOULD be checked at the start
119
+ of each feature planning cycle (`/speckit.plan` Constitution Check).
120
+
121
+ **Version**: 1.1.0 | **Ratified**: 2026-02-25 | **Last Amended**: 2026-02-25
.specify/scripts/bash/check-prerequisites.sh ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env bash
2
+
3
+ # Consolidated prerequisite checking script
4
+ #
5
+ # This script provides unified prerequisite checking for Spec-Driven Development workflow.
6
+ # It replaces the functionality previously spread across multiple scripts.
7
+ #
8
+ # Usage: ./check-prerequisites.sh [OPTIONS]
9
+ #
10
+ # OPTIONS:
11
+ # --json Output in JSON format
12
+ # --require-tasks Require tasks.md to exist (for implementation phase)
13
+ # --include-tasks Include tasks.md in AVAILABLE_DOCS list
14
+ # --paths-only Only output path variables (no validation)
15
+ # --help, -h Show help message
16
+ #
17
+ # OUTPUTS:
18
+ # JSON mode: {"FEATURE_DIR":"...", "AVAILABLE_DOCS":["..."]}
19
+ # Text mode: FEATURE_DIR:... \n AVAILABLE_DOCS: \n ✓/✗ file.md
20
+ # Paths only: REPO_ROOT: ... \n BRANCH: ... \n FEATURE_DIR: ... etc.
21
+
22
+ set -e
23
+
24
+ # Parse command line arguments
25
+ JSON_MODE=false
26
+ REQUIRE_TASKS=false
27
+ INCLUDE_TASKS=false
28
+ PATHS_ONLY=false
29
+
30
+ for arg in "$@"; do
31
+ case "$arg" in
32
+ --json)
33
+ JSON_MODE=true
34
+ ;;
35
+ --require-tasks)
36
+ REQUIRE_TASKS=true
37
+ ;;
38
+ --include-tasks)
39
+ INCLUDE_TASKS=true
40
+ ;;
41
+ --paths-only)
42
+ PATHS_ONLY=true
43
+ ;;
44
+ --help|-h)
45
+ cat << 'EOF'
46
+ Usage: check-prerequisites.sh [OPTIONS]
47
+
48
+ Consolidated prerequisite checking for Spec-Driven Development workflow.
49
+
50
+ OPTIONS:
51
+ --json Output in JSON format
52
+ --require-tasks Require tasks.md to exist (for implementation phase)
53
+ --include-tasks Include tasks.md in AVAILABLE_DOCS list
54
+ --paths-only Only output path variables (no prerequisite validation)
55
+ --help, -h Show this help message
56
+
57
+ EXAMPLES:
58
+ # Check task prerequisites (plan.md required)
59
+ ./check-prerequisites.sh --json
60
+
61
+ # Check implementation prerequisites (plan.md + tasks.md required)
62
+ ./check-prerequisites.sh --json --require-tasks --include-tasks
63
+
64
+ # Get feature paths only (no validation)
65
+ ./check-prerequisites.sh --paths-only
66
+
67
+ EOF
68
+ exit 0
69
+ ;;
70
+ *)
71
+ echo "ERROR: Unknown option '$arg'. Use --help for usage information." >&2
72
+ exit 1
73
+ ;;
74
+ esac
75
+ done
76
+
77
+ # Source common functions
78
+ SCRIPT_DIR="$(CDPATH="" cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
79
+ source "$SCRIPT_DIR/common.sh"
80
+
81
+ # Get feature paths and validate branch
82
+ eval $(get_feature_paths)
83
+ check_feature_branch "$CURRENT_BRANCH" "$HAS_GIT" || exit 1
84
+
85
+ # If paths-only mode, output paths and exit (support JSON + paths-only combined)
86
+ if $PATHS_ONLY; then
87
+ if $JSON_MODE; then
88
+ # Minimal JSON paths payload (no validation performed)
89
+ printf '{"REPO_ROOT":"%s","BRANCH":"%s","FEATURE_DIR":"%s","FEATURE_SPEC":"%s","IMPL_PLAN":"%s","TASKS":"%s"}\n' \
90
+ "$REPO_ROOT" "$CURRENT_BRANCH" "$FEATURE_DIR" "$FEATURE_SPEC" "$IMPL_PLAN" "$TASKS"
91
+ else
92
+ echo "REPO_ROOT: $REPO_ROOT"
93
+ echo "BRANCH: $CURRENT_BRANCH"
94
+ echo "FEATURE_DIR: $FEATURE_DIR"
95
+ echo "FEATURE_SPEC: $FEATURE_SPEC"
96
+ echo "IMPL_PLAN: $IMPL_PLAN"
97
+ echo "TASKS: $TASKS"
98
+ fi
99
+ exit 0
100
+ fi
101
+
102
+ # Validate required directories and files
103
+ if [[ ! -d "$FEATURE_DIR" ]]; then
104
+ echo "ERROR: Feature directory not found: $FEATURE_DIR" >&2
105
+ echo "Run /speckit.specify first to create the feature structure." >&2
106
+ exit 1
107
+ fi
108
+
109
+ if [[ ! -f "$IMPL_PLAN" ]]; then
110
+ echo "ERROR: plan.md not found in $FEATURE_DIR" >&2
111
+ echo "Run /speckit.plan first to create the implementation plan." >&2
112
+ exit 1
113
+ fi
114
+
115
+ # Check for tasks.md if required
116
+ if $REQUIRE_TASKS && [[ ! -f "$TASKS" ]]; then
117
+ echo "ERROR: tasks.md not found in $FEATURE_DIR" >&2
118
+ echo "Run /speckit.tasks first to create the task list." >&2
119
+ exit 1
120
+ fi
121
+
122
+ # Build list of available documents
123
+ docs=()
124
+
125
+ # Always check these optional docs
126
+ [[ -f "$RESEARCH" ]] && docs+=("research.md")
127
+ [[ -f "$DATA_MODEL" ]] && docs+=("data-model.md")
128
+
129
+ # Check contracts directory (only if it exists and has files)
130
+ if [[ -d "$CONTRACTS_DIR" ]] && [[ -n "$(ls -A "$CONTRACTS_DIR" 2>/dev/null)" ]]; then
131
+ docs+=("contracts/")
132
+ fi
133
+
134
+ [[ -f "$QUICKSTART" ]] && docs+=("quickstart.md")
135
+
136
+ # Include tasks.md if requested and it exists
137
+ if $INCLUDE_TASKS && [[ -f "$TASKS" ]]; then
138
+ docs+=("tasks.md")
139
+ fi
140
+
141
+ # Output results
142
+ if $JSON_MODE; then
143
+ # Build JSON array of documents
144
+ if [[ ${#docs[@]} -eq 0 ]]; then
145
+ json_docs="[]"
146
+ else
147
+ json_docs=$(printf '"%s",' "${docs[@]}")
148
+ json_docs="[${json_docs%,}]"
149
+ fi
150
+
151
+ printf '{"FEATURE_DIR":"%s","AVAILABLE_DOCS":%s}\n' "$FEATURE_DIR" "$json_docs"
152
+ else
153
+ # Text output
154
+ echo "FEATURE_DIR:$FEATURE_DIR"
155
+ echo "AVAILABLE_DOCS:"
156
+
157
+ # Show status of each potential document
158
+ check_file "$RESEARCH" "research.md"
159
+ check_file "$DATA_MODEL" "data-model.md"
160
+ check_dir "$CONTRACTS_DIR" "contracts/"
161
+ check_file "$QUICKSTART" "quickstart.md"
162
+
163
+ if $INCLUDE_TASKS; then
164
+ check_file "$TASKS" "tasks.md"
165
+ fi
166
+ fi
.specify/scripts/bash/common.sh ADDED
@@ -0,0 +1,156 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env bash
2
+ # Common functions and variables for all scripts
3
+
4
+ # Get repository root, with fallback for non-git repositories
5
+ get_repo_root() {
6
+ if git rev-parse --show-toplevel >/dev/null 2>&1; then
7
+ git rev-parse --show-toplevel
8
+ else
9
+ # Fall back to script location for non-git repos
10
+ local script_dir="$(CDPATH="" cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11
+ (cd "$script_dir/../../.." && pwd)
12
+ fi
13
+ }
14
+
15
+ # Get current branch, with fallback for non-git repositories
16
+ get_current_branch() {
17
+ # First check if SPECIFY_FEATURE environment variable is set
18
+ if [[ -n "${SPECIFY_FEATURE:-}" ]]; then
19
+ echo "$SPECIFY_FEATURE"
20
+ return
21
+ fi
22
+
23
+ # Then check git if available
24
+ if git rev-parse --abbrev-ref HEAD >/dev/null 2>&1; then
25
+ git rev-parse --abbrev-ref HEAD
26
+ return
27
+ fi
28
+
29
+ # For non-git repos, try to find the latest feature directory
30
+ local repo_root=$(get_repo_root)
31
+ local specs_dir="$repo_root/specs"
32
+
33
+ if [[ -d "$specs_dir" ]]; then
34
+ local latest_feature=""
35
+ local highest=0
36
+
37
+ for dir in "$specs_dir"/*; do
38
+ if [[ -d "$dir" ]]; then
39
+ local dirname=$(basename "$dir")
40
+ if [[ "$dirname" =~ ^([0-9]{3})- ]]; then
41
+ local number=${BASH_REMATCH[1]}
42
+ number=$((10#$number))
43
+ if [[ "$number" -gt "$highest" ]]; then
44
+ highest=$number
45
+ latest_feature=$dirname
46
+ fi
47
+ fi
48
+ fi
49
+ done
50
+
51
+ if [[ -n "$latest_feature" ]]; then
52
+ echo "$latest_feature"
53
+ return
54
+ fi
55
+ fi
56
+
57
+ echo "main" # Final fallback
58
+ }
59
+
60
+ # Check if we have git available
61
+ has_git() {
62
+ git rev-parse --show-toplevel >/dev/null 2>&1
63
+ }
64
+
65
+ check_feature_branch() {
66
+ local branch="$1"
67
+ local has_git_repo="$2"
68
+
69
+ # For non-git repos, we can't enforce branch naming but still provide output
70
+ if [[ "$has_git_repo" != "true" ]]; then
71
+ echo "[specify] Warning: Git repository not detected; skipped branch validation" >&2
72
+ return 0
73
+ fi
74
+
75
+ if [[ ! "$branch" =~ ^[0-9]{3}- ]]; then
76
+ echo "ERROR: Not on a feature branch. Current branch: $branch" >&2
77
+ echo "Feature branches should be named like: 001-feature-name" >&2
78
+ return 1
79
+ fi
80
+
81
+ return 0
82
+ }
83
+
84
+ get_feature_dir() { echo "$1/specs/$2"; }
85
+
86
+ # Find feature directory by numeric prefix instead of exact branch match
87
+ # This allows multiple branches to work on the same spec (e.g., 004-fix-bug, 004-add-feature)
88
+ find_feature_dir_by_prefix() {
89
+ local repo_root="$1"
90
+ local branch_name="$2"
91
+ local specs_dir="$repo_root/specs"
92
+
93
+ # Extract numeric prefix from branch (e.g., "004" from "004-whatever")
94
+ if [[ ! "$branch_name" =~ ^([0-9]{3})- ]]; then
95
+ # If branch doesn't have numeric prefix, fall back to exact match
96
+ echo "$specs_dir/$branch_name"
97
+ return
98
+ fi
99
+
100
+ local prefix="${BASH_REMATCH[1]}"
101
+
102
+ # Search for directories in specs/ that start with this prefix
103
+ local matches=()
104
+ if [[ -d "$specs_dir" ]]; then
105
+ for dir in "$specs_dir"/"$prefix"-*; do
106
+ if [[ -d "$dir" ]]; then
107
+ matches+=("$(basename "$dir")")
108
+ fi
109
+ done
110
+ fi
111
+
112
+ # Handle results
113
+ if [[ ${#matches[@]} -eq 0 ]]; then
114
+ # No match found - return the branch name path (will fail later with clear error)
115
+ echo "$specs_dir/$branch_name"
116
+ elif [[ ${#matches[@]} -eq 1 ]]; then
117
+ # Exactly one match - perfect!
118
+ echo "$specs_dir/${matches[0]}"
119
+ else
120
+ # Multiple matches - this shouldn't happen with proper naming convention
121
+ echo "ERROR: Multiple spec directories found with prefix '$prefix': ${matches[*]}" >&2
122
+ echo "Please ensure only one spec directory exists per numeric prefix." >&2
123
+ echo "$specs_dir/$branch_name" # Return something to avoid breaking the script
124
+ fi
125
+ }
126
+
127
+ get_feature_paths() {
128
+ local repo_root=$(get_repo_root)
129
+ local current_branch=$(get_current_branch)
130
+ local has_git_repo="false"
131
+
132
+ if has_git; then
133
+ has_git_repo="true"
134
+ fi
135
+
136
+ # Use prefix-based lookup to support multiple branches per spec
137
+ local feature_dir=$(find_feature_dir_by_prefix "$repo_root" "$current_branch")
138
+
139
+ cat <<EOF
140
+ REPO_ROOT='$repo_root'
141
+ CURRENT_BRANCH='$current_branch'
142
+ HAS_GIT='$has_git_repo'
143
+ FEATURE_DIR='$feature_dir'
144
+ FEATURE_SPEC='$feature_dir/spec.md'
145
+ IMPL_PLAN='$feature_dir/plan.md'
146
+ TASKS='$feature_dir/tasks.md'
147
+ RESEARCH='$feature_dir/research.md'
148
+ DATA_MODEL='$feature_dir/data-model.md'
149
+ QUICKSTART='$feature_dir/quickstart.md'
150
+ CONTRACTS_DIR='$feature_dir/contracts'
151
+ EOF
152
+ }
153
+
154
+ check_file() { [[ -f "$1" ]] && echo " ✓ $2" || echo " ✗ $2"; }
155
+ check_dir() { [[ -d "$1" && -n $(ls -A "$1" 2>/dev/null) ]] && echo " ✓ $2" || echo " ✗ $2"; }
156
+
.specify/scripts/bash/create-new-feature.sh ADDED
@@ -0,0 +1,297 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env bash
2
+
3
+ set -e
4
+
5
+ JSON_MODE=false
6
+ SHORT_NAME=""
7
+ BRANCH_NUMBER=""
8
+ ARGS=()
9
+ i=1
10
+ while [ $i -le $# ]; do
11
+ arg="${!i}"
12
+ case "$arg" in
13
+ --json)
14
+ JSON_MODE=true
15
+ ;;
16
+ --short-name)
17
+ if [ $((i + 1)) -gt $# ]; then
18
+ echo 'Error: --short-name requires a value' >&2
19
+ exit 1
20
+ fi
21
+ i=$((i + 1))
22
+ next_arg="${!i}"
23
+ # Check if the next argument is another option (starts with --)
24
+ if [[ "$next_arg" == --* ]]; then
25
+ echo 'Error: --short-name requires a value' >&2
26
+ exit 1
27
+ fi
28
+ SHORT_NAME="$next_arg"
29
+ ;;
30
+ --number)
31
+ if [ $((i + 1)) -gt $# ]; then
32
+ echo 'Error: --number requires a value' >&2
33
+ exit 1
34
+ fi
35
+ i=$((i + 1))
36
+ next_arg="${!i}"
37
+ if [[ "$next_arg" == --* ]]; then
38
+ echo 'Error: --number requires a value' >&2
39
+ exit 1
40
+ fi
41
+ BRANCH_NUMBER="$next_arg"
42
+ ;;
43
+ --help|-h)
44
+ echo "Usage: $0 [--json] [--short-name <name>] [--number N] <feature_description>"
45
+ echo ""
46
+ echo "Options:"
47
+ echo " --json Output in JSON format"
48
+ echo " --short-name <name> Provide a custom short name (2-4 words) for the branch"
49
+ echo " --number N Specify branch number manually (overrides auto-detection)"
50
+ echo " --help, -h Show this help message"
51
+ echo ""
52
+ echo "Examples:"
53
+ echo " $0 'Add user authentication system' --short-name 'user-auth'"
54
+ echo " $0 'Implement OAuth2 integration for API' --number 5"
55
+ exit 0
56
+ ;;
57
+ *)
58
+ ARGS+=("$arg")
59
+ ;;
60
+ esac
61
+ i=$((i + 1))
62
+ done
63
+
64
+ FEATURE_DESCRIPTION="${ARGS[*]}"
65
+ if [ -z "$FEATURE_DESCRIPTION" ]; then
66
+ echo "Usage: $0 [--json] [--short-name <name>] [--number N] <feature_description>" >&2
67
+ exit 1
68
+ fi
69
+
70
+ # Function to find the repository root by searching for existing project markers
71
+ find_repo_root() {
72
+ local dir="$1"
73
+ while [ "$dir" != "/" ]; do
74
+ if [ -d "$dir/.git" ] || [ -d "$dir/.specify" ]; then
75
+ echo "$dir"
76
+ return 0
77
+ fi
78
+ dir="$(dirname "$dir")"
79
+ done
80
+ return 1
81
+ }
82
+
83
+ # Function to get highest number from specs directory
84
+ get_highest_from_specs() {
85
+ local specs_dir="$1"
86
+ local highest=0
87
+
88
+ if [ -d "$specs_dir" ]; then
89
+ for dir in "$specs_dir"/*; do
90
+ [ -d "$dir" ] || continue
91
+ dirname=$(basename "$dir")
92
+ number=$(echo "$dirname" | grep -o '^[0-9]\+' || echo "0")
93
+ number=$((10#$number))
94
+ if [ "$number" -gt "$highest" ]; then
95
+ highest=$number
96
+ fi
97
+ done
98
+ fi
99
+
100
+ echo "$highest"
101
+ }
102
+
103
+ # Function to get highest number from git branches
104
+ get_highest_from_branches() {
105
+ local highest=0
106
+
107
+ # Get all branches (local and remote)
108
+ branches=$(git branch -a 2>/dev/null || echo "")
109
+
110
+ if [ -n "$branches" ]; then
111
+ while IFS= read -r branch; do
112
+ # Clean branch name: remove leading markers and remote prefixes
113
+ clean_branch=$(echo "$branch" | sed 's/^[* ]*//; s|^remotes/[^/]*/||')
114
+
115
+ # Extract feature number if branch matches pattern ###-*
116
+ if echo "$clean_branch" | grep -q '^[0-9]\{3\}-'; then
117
+ number=$(echo "$clean_branch" | grep -o '^[0-9]\{3\}' || echo "0")
118
+ number=$((10#$number))
119
+ if [ "$number" -gt "$highest" ]; then
120
+ highest=$number
121
+ fi
122
+ fi
123
+ done <<< "$branches"
124
+ fi
125
+
126
+ echo "$highest"
127
+ }
128
+
129
+ # Function to check existing branches (local and remote) and return next available number
130
+ check_existing_branches() {
131
+ local specs_dir="$1"
132
+
133
+ # Fetch all remotes to get latest branch info (suppress errors if no remotes)
134
+ git fetch --all --prune 2>/dev/null || true
135
+
136
+ # Get highest number from ALL branches (not just matching short name)
137
+ local highest_branch=$(get_highest_from_branches)
138
+
139
+ # Get highest number from ALL specs (not just matching short name)
140
+ local highest_spec=$(get_highest_from_specs "$specs_dir")
141
+
142
+ # Take the maximum of both
143
+ local max_num=$highest_branch
144
+ if [ "$highest_spec" -gt "$max_num" ]; then
145
+ max_num=$highest_spec
146
+ fi
147
+
148
+ # Return next number
149
+ echo $((max_num + 1))
150
+ }
151
+
152
+ # Function to clean and format a branch name
153
+ clean_branch_name() {
154
+ local name="$1"
155
+ echo "$name" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | sed 's/-\+/-/g' | sed 's/^-//' | sed 's/-$//'
156
+ }
157
+
158
+ # Resolve repository root. Prefer git information when available, but fall back
159
+ # to searching for repository markers so the workflow still functions in repositories that
160
+ # were initialised with --no-git.
161
+ SCRIPT_DIR="$(CDPATH="" cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
162
+
163
+ if git rev-parse --show-toplevel >/dev/null 2>&1; then
164
+ REPO_ROOT=$(git rev-parse --show-toplevel)
165
+ HAS_GIT=true
166
+ else
167
+ REPO_ROOT="$(find_repo_root "$SCRIPT_DIR")"
168
+ if [ -z "$REPO_ROOT" ]; then
169
+ echo "Error: Could not determine repository root. Please run this script from within the repository." >&2
170
+ exit 1
171
+ fi
172
+ HAS_GIT=false
173
+ fi
174
+
175
+ cd "$REPO_ROOT"
176
+
177
+ SPECS_DIR="$REPO_ROOT/specs"
178
+ mkdir -p "$SPECS_DIR"
179
+
180
+ # Function to generate branch name with stop word filtering and length filtering
181
+ generate_branch_name() {
182
+ local description="$1"
183
+
184
+ # Common stop words to filter out
185
+ local stop_words="^(i|a|an|the|to|for|of|in|on|at|by|with|from|is|are|was|were|be|been|being|have|has|had|do|does|did|will|would|should|could|can|may|might|must|shall|this|that|these|those|my|your|our|their|want|need|add|get|set)$"
186
+
187
+ # Convert to lowercase and split into words
188
+ local clean_name=$(echo "$description" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/ /g')
189
+
190
+ # Filter words: remove stop words and words shorter than 3 chars (unless they're uppercase acronyms in original)
191
+ local meaningful_words=()
192
+ for word in $clean_name; do
193
+ # Skip empty words
194
+ [ -z "$word" ] && continue
195
+
196
+ # Keep words that are NOT stop words AND (length >= 3 OR are potential acronyms)
197
+ if ! echo "$word" | grep -qiE "$stop_words"; then
198
+ if [ ${#word} -ge 3 ]; then
199
+ meaningful_words+=("$word")
200
+ elif echo "$description" | grep -q "\b${word^^}\b"; then
201
+ # Keep short words if they appear as uppercase in original (likely acronyms)
202
+ meaningful_words+=("$word")
203
+ fi
204
+ fi
205
+ done
206
+
207
+ # If we have meaningful words, use first 3-4 of them
208
+ if [ ${#meaningful_words[@]} -gt 0 ]; then
209
+ local max_words=3
210
+ if [ ${#meaningful_words[@]} -eq 4 ]; then max_words=4; fi
211
+
212
+ local result=""
213
+ local count=0
214
+ for word in "${meaningful_words[@]}"; do
215
+ if [ $count -ge $max_words ]; then break; fi
216
+ if [ -n "$result" ]; then result="$result-"; fi
217
+ result="$result$word"
218
+ count=$((count + 1))
219
+ done
220
+ echo "$result"
221
+ else
222
+ # Fallback to original logic if no meaningful words found
223
+ local cleaned=$(clean_branch_name "$description")
224
+ echo "$cleaned" | tr '-' '\n' | grep -v '^$' | head -3 | tr '\n' '-' | sed 's/-$//'
225
+ fi
226
+ }
227
+
228
+ # Generate branch name
229
+ if [ -n "$SHORT_NAME" ]; then
230
+ # Use provided short name, just clean it up
231
+ BRANCH_SUFFIX=$(clean_branch_name "$SHORT_NAME")
232
+ else
233
+ # Generate from description with smart filtering
234
+ BRANCH_SUFFIX=$(generate_branch_name "$FEATURE_DESCRIPTION")
235
+ fi
236
+
237
+ # Determine branch number
238
+ if [ -z "$BRANCH_NUMBER" ]; then
239
+ if [ "$HAS_GIT" = true ]; then
240
+ # Check existing branches on remotes
241
+ BRANCH_NUMBER=$(check_existing_branches "$SPECS_DIR")
242
+ else
243
+ # Fall back to local directory check
244
+ HIGHEST=$(get_highest_from_specs "$SPECS_DIR")
245
+ BRANCH_NUMBER=$((HIGHEST + 1))
246
+ fi
247
+ fi
248
+
249
+ # Force base-10 interpretation to prevent octal conversion (e.g., 010 → 8 in octal, but should be 10 in decimal)
250
+ FEATURE_NUM=$(printf "%03d" "$((10#$BRANCH_NUMBER))")
251
+ BRANCH_NAME="${FEATURE_NUM}-${BRANCH_SUFFIX}"
252
+
253
+ # GitHub enforces a 244-byte limit on branch names
254
+ # Validate and truncate if necessary
255
+ MAX_BRANCH_LENGTH=244
256
+ if [ ${#BRANCH_NAME} -gt $MAX_BRANCH_LENGTH ]; then
257
+ # Calculate how much we need to trim from suffix
258
+ # Account for: feature number (3) + hyphen (1) = 4 chars
259
+ MAX_SUFFIX_LENGTH=$((MAX_BRANCH_LENGTH - 4))
260
+
261
+ # Truncate suffix at word boundary if possible
262
+ TRUNCATED_SUFFIX=$(echo "$BRANCH_SUFFIX" | cut -c1-$MAX_SUFFIX_LENGTH)
263
+ # Remove trailing hyphen if truncation created one
264
+ TRUNCATED_SUFFIX=$(echo "$TRUNCATED_SUFFIX" | sed 's/-$//')
265
+
266
+ ORIGINAL_BRANCH_NAME="$BRANCH_NAME"
267
+ BRANCH_NAME="${FEATURE_NUM}-${TRUNCATED_SUFFIX}"
268
+
269
+ >&2 echo "[specify] Warning: Branch name exceeded GitHub's 244-byte limit"
270
+ >&2 echo "[specify] Original: $ORIGINAL_BRANCH_NAME (${#ORIGINAL_BRANCH_NAME} bytes)"
271
+ >&2 echo "[specify] Truncated to: $BRANCH_NAME (${#BRANCH_NAME} bytes)"
272
+ fi
273
+
274
+ if [ "$HAS_GIT" = true ]; then
275
+ git checkout -b "$BRANCH_NAME"
276
+ else
277
+ >&2 echo "[specify] Warning: Git repository not detected; skipped branch creation for $BRANCH_NAME"
278
+ fi
279
+
280
+ FEATURE_DIR="$SPECS_DIR/$BRANCH_NAME"
281
+ mkdir -p "$FEATURE_DIR"
282
+
283
+ TEMPLATE="$REPO_ROOT/.specify/templates/spec-template.md"
284
+ SPEC_FILE="$FEATURE_DIR/spec.md"
285
+ if [ -f "$TEMPLATE" ]; then cp "$TEMPLATE" "$SPEC_FILE"; else touch "$SPEC_FILE"; fi
286
+
287
+ # Set the SPECIFY_FEATURE environment variable for the current session
288
+ export SPECIFY_FEATURE="$BRANCH_NAME"
289
+
290
+ if $JSON_MODE; then
291
+ printf '{"BRANCH_NAME":"%s","SPEC_FILE":"%s","FEATURE_NUM":"%s"}\n' "$BRANCH_NAME" "$SPEC_FILE" "$FEATURE_NUM"
292
+ else
293
+ echo "BRANCH_NAME: $BRANCH_NAME"
294
+ echo "SPEC_FILE: $SPEC_FILE"
295
+ echo "FEATURE_NUM: $FEATURE_NUM"
296
+ echo "SPECIFY_FEATURE environment variable set to: $BRANCH_NAME"
297
+ fi
.specify/scripts/bash/setup-plan.sh ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env bash
2
+
3
+ set -e
4
+
5
+ # Parse command line arguments
6
+ JSON_MODE=false
7
+ ARGS=()
8
+
9
+ for arg in "$@"; do
10
+ case "$arg" in
11
+ --json)
12
+ JSON_MODE=true
13
+ ;;
14
+ --help|-h)
15
+ echo "Usage: $0 [--json]"
16
+ echo " --json Output results in JSON format"
17
+ echo " --help Show this help message"
18
+ exit 0
19
+ ;;
20
+ *)
21
+ ARGS+=("$arg")
22
+ ;;
23
+ esac
24
+ done
25
+
26
+ # Get script directory and load common functions
27
+ SCRIPT_DIR="$(CDPATH="" cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
28
+ source "$SCRIPT_DIR/common.sh"
29
+
30
+ # Get all paths and variables from common functions
31
+ eval $(get_feature_paths)
32
+
33
+ # Check if we're on a proper feature branch (only for git repos)
34
+ check_feature_branch "$CURRENT_BRANCH" "$HAS_GIT" || exit 1
35
+
36
+ # Ensure the feature directory exists
37
+ mkdir -p "$FEATURE_DIR"
38
+
39
+ # Copy plan template if it exists
40
+ TEMPLATE="$REPO_ROOT/.specify/templates/plan-template.md"
41
+ if [[ -f "$TEMPLATE" ]]; then
42
+ cp "$TEMPLATE" "$IMPL_PLAN"
43
+ echo "Copied plan template to $IMPL_PLAN"
44
+ else
45
+ echo "Warning: Plan template not found at $TEMPLATE"
46
+ # Create a basic plan file if template doesn't exist
47
+ touch "$IMPL_PLAN"
48
+ fi
49
+
50
+ # Output results
51
+ if $JSON_MODE; then
52
+ printf '{"FEATURE_SPEC":"%s","IMPL_PLAN":"%s","SPECS_DIR":"%s","BRANCH":"%s","HAS_GIT":"%s"}\n' \
53
+ "$FEATURE_SPEC" "$IMPL_PLAN" "$FEATURE_DIR" "$CURRENT_BRANCH" "$HAS_GIT"
54
+ else
55
+ echo "FEATURE_SPEC: $FEATURE_SPEC"
56
+ echo "IMPL_PLAN: $IMPL_PLAN"
57
+ echo "SPECS_DIR: $FEATURE_DIR"
58
+ echo "BRANCH: $CURRENT_BRANCH"
59
+ echo "HAS_GIT: $HAS_GIT"
60
+ fi
61
+
.specify/scripts/bash/update-agent-context.sh ADDED
@@ -0,0 +1,810 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env bash
2
+
3
+ # Update agent context files with information from plan.md
4
+ #
5
+ # This script maintains AI agent context files by parsing feature specifications
6
+ # and updating agent-specific configuration files with project information.
7
+ #
8
+ # MAIN FUNCTIONS:
9
+ # 1. Environment Validation
10
+ # - Verifies git repository structure and branch information
11
+ # - Checks for required plan.md files and templates
12
+ # - Validates file permissions and accessibility
13
+ #
14
+ # 2. Plan Data Extraction
15
+ # - Parses plan.md files to extract project metadata
16
+ # - Identifies language/version, frameworks, databases, and project types
17
+ # - Handles missing or incomplete specification data gracefully
18
+ #
19
+ # 3. Agent File Management
20
+ # - Creates new agent context files from templates when needed
21
+ # - Updates existing agent files with new project information
22
+ # - Preserves manual additions and custom configurations
23
+ # - Supports multiple AI agent formats and directory structures
24
+ #
25
+ # 4. Content Generation
26
+ # - Generates language-specific build/test commands
27
+ # - Creates appropriate project directory structures
28
+ # - Updates technology stacks and recent changes sections
29
+ # - Maintains consistent formatting and timestamps
30
+ #
31
+ # 5. Multi-Agent Support
32
+ # - Handles agent-specific file paths and naming conventions
33
+ # - Supports: Claude, Gemini, Copilot, Cursor, Qwen, opencode, Codex, Windsurf, Kilo Code, Auggie CLI, Roo Code, CodeBuddy CLI, Qoder CLI, Amp, SHAI, Amazon Q Developer CLI, or Antigravity
34
+ # - Can update single agents or all existing agent files
35
+ # - Creates default Claude file if no agent files exist
36
+ #
37
+ # Usage: ./update-agent-context.sh [agent_type]
38
+ # Agent types: claude|gemini|copilot|cursor-agent|qwen|opencode|codex|windsurf|kilocode|auggie|roo|codebuddy|amp|shai|q|agy|bob|qodercli
39
+ # Leave empty to update all existing agent files
40
+
41
+ set -e
42
+
43
+ # Enable strict error handling
44
+ set -u
45
+ set -o pipefail
46
+
47
+ #==============================================================================
48
+ # Configuration and Global Variables
49
+ #==============================================================================
50
+
51
+ # Get script directory and load common functions
52
+ SCRIPT_DIR="$(CDPATH="" cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
53
+ source "$SCRIPT_DIR/common.sh"
54
+
55
+ # Get all paths and variables from common functions
56
+ eval $(get_feature_paths)
57
+
58
+ NEW_PLAN="$IMPL_PLAN" # Alias for compatibility with existing code
59
+ AGENT_TYPE="${1:-}"
60
+
61
+ # Agent-specific file paths
62
+ CLAUDE_FILE="$REPO_ROOT/CLAUDE.md"
63
+ GEMINI_FILE="$REPO_ROOT/GEMINI.md"
64
+ COPILOT_FILE="$REPO_ROOT/.github/agents/copilot-instructions.md"
65
+ CURSOR_FILE="$REPO_ROOT/.cursor/rules/specify-rules.mdc"
66
+ QWEN_FILE="$REPO_ROOT/QWEN.md"
67
+ AGENTS_FILE="$REPO_ROOT/AGENTS.md"
68
+ WINDSURF_FILE="$REPO_ROOT/.windsurf/rules/specify-rules.md"
69
+ KILOCODE_FILE="$REPO_ROOT/.kilocode/rules/specify-rules.md"
70
+ AUGGIE_FILE="$REPO_ROOT/.augment/rules/specify-rules.md"
71
+ ROO_FILE="$REPO_ROOT/.roo/rules/specify-rules.md"
72
+ CODEBUDDY_FILE="$REPO_ROOT/CODEBUDDY.md"
73
+ QODER_FILE="$REPO_ROOT/QODER.md"
74
+ AMP_FILE="$REPO_ROOT/AGENTS.md"
75
+ SHAI_FILE="$REPO_ROOT/SHAI.md"
76
+ Q_FILE="$REPO_ROOT/AGENTS.md"
77
+ AGY_FILE="$REPO_ROOT/.agent/rules/specify-rules.md"
78
+ BOB_FILE="$REPO_ROOT/AGENTS.md"
79
+
80
+ # Template file
81
+ TEMPLATE_FILE="$REPO_ROOT/.specify/templates/agent-file-template.md"
82
+
83
+ # Global variables for parsed plan data
84
+ NEW_LANG=""
85
+ NEW_FRAMEWORK=""
86
+ NEW_DB=""
87
+ NEW_PROJECT_TYPE=""
88
+
89
+ #==============================================================================
90
+ # Utility Functions
91
+ #==============================================================================
92
+
93
+ log_info() {
94
+ echo "INFO: $1"
95
+ }
96
+
97
+ log_success() {
98
+ echo "✓ $1"
99
+ }
100
+
101
+ log_error() {
102
+ echo "ERROR: $1" >&2
103
+ }
104
+
105
+ log_warning() {
106
+ echo "WARNING: $1" >&2
107
+ }
108
+
109
+ # Cleanup function for temporary files
110
+ cleanup() {
111
+ local exit_code=$?
112
+ rm -f /tmp/agent_update_*_$$
113
+ rm -f /tmp/manual_additions_$$
114
+ exit $exit_code
115
+ }
116
+
117
+ # Set up cleanup trap
118
+ trap cleanup EXIT INT TERM
119
+
120
+ #==============================================================================
121
+ # Validation Functions
122
+ #==============================================================================
123
+
124
+ validate_environment() {
125
+ # Check if we have a current branch/feature (git or non-git)
126
+ if [[ -z "$CURRENT_BRANCH" ]]; then
127
+ log_error "Unable to determine current feature"
128
+ if [[ "$HAS_GIT" == "true" ]]; then
129
+ log_info "Make sure you're on a feature branch"
130
+ else
131
+ log_info "Set SPECIFY_FEATURE environment variable or create a feature first"
132
+ fi
133
+ exit 1
134
+ fi
135
+
136
+ # Check if plan.md exists
137
+ if [[ ! -f "$NEW_PLAN" ]]; then
138
+ log_error "No plan.md found at $NEW_PLAN"
139
+ log_info "Make sure you're working on a feature with a corresponding spec directory"
140
+ if [[ "$HAS_GIT" != "true" ]]; then
141
+ log_info "Use: export SPECIFY_FEATURE=your-feature-name or create a new feature first"
142
+ fi
143
+ exit 1
144
+ fi
145
+
146
+ # Check if template exists (needed for new files)
147
+ if [[ ! -f "$TEMPLATE_FILE" ]]; then
148
+ log_warning "Template file not found at $TEMPLATE_FILE"
149
+ log_warning "Creating new agent files will fail"
150
+ fi
151
+ }
152
+
153
+ #==============================================================================
154
+ # Plan Parsing Functions
155
+ #==============================================================================
156
+
157
+ extract_plan_field() {
158
+ local field_pattern="$1"
159
+ local plan_file="$2"
160
+
161
+ grep "^\*\*${field_pattern}\*\*: " "$plan_file" 2>/dev/null | \
162
+ head -1 | \
163
+ sed "s|^\*\*${field_pattern}\*\*: ||" | \
164
+ sed 's/^[ \t]*//;s/[ \t]*$//' | \
165
+ grep -v "NEEDS CLARIFICATION" | \
166
+ grep -v "^N/A$" || echo ""
167
+ }
168
+
169
+ parse_plan_data() {
170
+ local plan_file="$1"
171
+
172
+ if [[ ! -f "$plan_file" ]]; then
173
+ log_error "Plan file not found: $plan_file"
174
+ return 1
175
+ fi
176
+
177
+ if [[ ! -r "$plan_file" ]]; then
178
+ log_error "Plan file is not readable: $plan_file"
179
+ return 1
180
+ fi
181
+
182
+ log_info "Parsing plan data from $plan_file"
183
+
184
+ NEW_LANG=$(extract_plan_field "Language/Version" "$plan_file")
185
+ NEW_FRAMEWORK=$(extract_plan_field "Primary Dependencies" "$plan_file")
186
+ NEW_DB=$(extract_plan_field "Storage" "$plan_file")
187
+ NEW_PROJECT_TYPE=$(extract_plan_field "Project Type" "$plan_file")
188
+
189
+ # Log what we found
190
+ if [[ -n "$NEW_LANG" ]]; then
191
+ log_info "Found language: $NEW_LANG"
192
+ else
193
+ log_warning "No language information found in plan"
194
+ fi
195
+
196
+ if [[ -n "$NEW_FRAMEWORK" ]]; then
197
+ log_info "Found framework: $NEW_FRAMEWORK"
198
+ fi
199
+
200
+ if [[ -n "$NEW_DB" ]] && [[ "$NEW_DB" != "N/A" ]]; then
201
+ log_info "Found database: $NEW_DB"
202
+ fi
203
+
204
+ if [[ -n "$NEW_PROJECT_TYPE" ]]; then
205
+ log_info "Found project type: $NEW_PROJECT_TYPE"
206
+ fi
207
+ }
208
+
209
+ format_technology_stack() {
210
+ local lang="$1"
211
+ local framework="$2"
212
+ local parts=()
213
+
214
+ # Add non-empty parts
215
+ [[ -n "$lang" && "$lang" != "NEEDS CLARIFICATION" ]] && parts+=("$lang")
216
+ [[ -n "$framework" && "$framework" != "NEEDS CLARIFICATION" && "$framework" != "N/A" ]] && parts+=("$framework")
217
+
218
+ # Join with proper formatting
219
+ if [[ ${#parts[@]} -eq 0 ]]; then
220
+ echo ""
221
+ elif [[ ${#parts[@]} -eq 1 ]]; then
222
+ echo "${parts[0]}"
223
+ else
224
+ # Join multiple parts with " + "
225
+ local result="${parts[0]}"
226
+ for ((i=1; i<${#parts[@]}; i++)); do
227
+ result="$result + ${parts[i]}"
228
+ done
229
+ echo "$result"
230
+ fi
231
+ }
232
+
233
+ #==============================================================================
234
+ # Template and Content Generation Functions
235
+ #==============================================================================
236
+
237
+ get_project_structure() {
238
+ local project_type="$1"
239
+
240
+ if [[ "$project_type" == *"web"* ]]; then
241
+ echo "backend/\\nfrontend/\\ntests/"
242
+ else
243
+ echo "src/\\ntests/"
244
+ fi
245
+ }
246
+
247
+ get_commands_for_language() {
248
+ local lang="$1"
249
+
250
+ case "$lang" in
251
+ *"Python"*)
252
+ echo "cd src && pytest && ruff check ."
253
+ ;;
254
+ *"Rust"*)
255
+ echo "cargo test && cargo clippy"
256
+ ;;
257
+ *"JavaScript"*|*"TypeScript"*)
258
+ echo "npm test \\&\\& npm run lint"
259
+ ;;
260
+ *)
261
+ echo "# Add commands for $lang"
262
+ ;;
263
+ esac
264
+ }
265
+
266
+ get_language_conventions() {
267
+ local lang="$1"
268
+ echo "$lang: Follow standard conventions"
269
+ }
270
+
271
+ create_new_agent_file() {
272
+ local target_file="$1"
273
+ local temp_file="$2"
274
+ local project_name="$3"
275
+ local current_date="$4"
276
+
277
+ if [[ ! -f "$TEMPLATE_FILE" ]]; then
278
+ log_error "Template not found at $TEMPLATE_FILE"
279
+ return 1
280
+ fi
281
+
282
+ if [[ ! -r "$TEMPLATE_FILE" ]]; then
283
+ log_error "Template file is not readable: $TEMPLATE_FILE"
284
+ return 1
285
+ fi
286
+
287
+ log_info "Creating new agent context file from template..."
288
+
289
+ if ! cp "$TEMPLATE_FILE" "$temp_file"; then
290
+ log_error "Failed to copy template file"
291
+ return 1
292
+ fi
293
+
294
+ # Replace template placeholders
295
+ local project_structure
296
+ project_structure=$(get_project_structure "$NEW_PROJECT_TYPE")
297
+
298
+ local commands
299
+ commands=$(get_commands_for_language "$NEW_LANG")
300
+
301
+ local language_conventions
302
+ language_conventions=$(get_language_conventions "$NEW_LANG")
303
+
304
+ # Perform substitutions with error checking using safer approach
305
+ # Escape special characters for sed by using a different delimiter or escaping
306
+ local escaped_lang=$(printf '%s\n' "$NEW_LANG" | sed 's/[\[\.*^$()+{}|]/\\&/g')
307
+ local escaped_framework=$(printf '%s\n' "$NEW_FRAMEWORK" | sed 's/[\[\.*^$()+{}|]/\\&/g')
308
+ local escaped_branch=$(printf '%s\n' "$CURRENT_BRANCH" | sed 's/[\[\.*^$()+{}|]/\\&/g')
309
+
310
+ # Build technology stack and recent change strings conditionally
311
+ local tech_stack
312
+ if [[ -n "$escaped_lang" && -n "$escaped_framework" ]]; then
313
+ tech_stack="- $escaped_lang + $escaped_framework ($escaped_branch)"
314
+ elif [[ -n "$escaped_lang" ]]; then
315
+ tech_stack="- $escaped_lang ($escaped_branch)"
316
+ elif [[ -n "$escaped_framework" ]]; then
317
+ tech_stack="- $escaped_framework ($escaped_branch)"
318
+ else
319
+ tech_stack="- ($escaped_branch)"
320
+ fi
321
+
322
+ local recent_change
323
+ if [[ -n "$escaped_lang" && -n "$escaped_framework" ]]; then
324
+ recent_change="- $escaped_branch: Added $escaped_lang + $escaped_framework"
325
+ elif [[ -n "$escaped_lang" ]]; then
326
+ recent_change="- $escaped_branch: Added $escaped_lang"
327
+ elif [[ -n "$escaped_framework" ]]; then
328
+ recent_change="- $escaped_branch: Added $escaped_framework"
329
+ else
330
+ recent_change="- $escaped_branch: Added"
331
+ fi
332
+
333
+ local substitutions=(
334
+ "s|\[PROJECT NAME\]|$project_name|"
335
+ "s|\[DATE\]|$current_date|"
336
+ "s|\[EXTRACTED FROM ALL PLAN.MD FILES\]|$tech_stack|"
337
+ "s|\[ACTUAL STRUCTURE FROM PLANS\]|$project_structure|g"
338
+ "s|\[ONLY COMMANDS FOR ACTIVE TECHNOLOGIES\]|$commands|"
339
+ "s|\[LANGUAGE-SPECIFIC, ONLY FOR LANGUAGES IN USE\]|$language_conventions|"
340
+ "s|\[LAST 3 FEATURES AND WHAT THEY ADDED\]|$recent_change|"
341
+ )
342
+
343
+ for substitution in "${substitutions[@]}"; do
344
+ if ! sed -i.bak -e "$substitution" "$temp_file"; then
345
+ log_error "Failed to perform substitution: $substitution"
346
+ rm -f "$temp_file" "$temp_file.bak"
347
+ return 1
348
+ fi
349
+ done
350
+
351
+ # Convert \n sequences to actual newlines
352
+ newline=$(printf '\n')
353
+ sed -i.bak2 "s/\\\\n/${newline}/g" "$temp_file"
354
+
355
+ # Clean up backup files
356
+ rm -f "$temp_file.bak" "$temp_file.bak2"
357
+
358
+ return 0
359
+ }
360
+
361
+
362
+
363
+
364
+ update_existing_agent_file() {
365
+ local target_file="$1"
366
+ local current_date="$2"
367
+
368
+ log_info "Updating existing agent context file..."
369
+
370
+ # Use a single temporary file for atomic update
371
+ local temp_file
372
+ temp_file=$(mktemp) || {
373
+ log_error "Failed to create temporary file"
374
+ return 1
375
+ }
376
+
377
+ # Process the file in one pass
378
+ local tech_stack=$(format_technology_stack "$NEW_LANG" "$NEW_FRAMEWORK")
379
+ local new_tech_entries=()
380
+ local new_change_entry=""
381
+
382
+ # Prepare new technology entries
383
+ if [[ -n "$tech_stack" ]] && ! grep -q "$tech_stack" "$target_file"; then
384
+ new_tech_entries+=("- $tech_stack ($CURRENT_BRANCH)")
385
+ fi
386
+
387
+ if [[ -n "$NEW_DB" ]] && [[ "$NEW_DB" != "N/A" ]] && [[ "$NEW_DB" != "NEEDS CLARIFICATION" ]] && ! grep -q "$NEW_DB" "$target_file"; then
388
+ new_tech_entries+=("- $NEW_DB ($CURRENT_BRANCH)")
389
+ fi
390
+
391
+ # Prepare new change entry
392
+ if [[ -n "$tech_stack" ]]; then
393
+ new_change_entry="- $CURRENT_BRANCH: Added $tech_stack"
394
+ elif [[ -n "$NEW_DB" ]] && [[ "$NEW_DB" != "N/A" ]] && [[ "$NEW_DB" != "NEEDS CLARIFICATION" ]]; then
395
+ new_change_entry="- $CURRENT_BRANCH: Added $NEW_DB"
396
+ fi
397
+
398
+ # Check if sections exist in the file
399
+ local has_active_technologies=0
400
+ local has_recent_changes=0
401
+
402
+ if grep -q "^## Active Technologies" "$target_file" 2>/dev/null; then
403
+ has_active_technologies=1
404
+ fi
405
+
406
+ if grep -q "^## Recent Changes" "$target_file" 2>/dev/null; then
407
+ has_recent_changes=1
408
+ fi
409
+
410
+ # Process file line by line
411
+ local in_tech_section=false
412
+ local in_changes_section=false
413
+ local tech_entries_added=false
414
+ local changes_entries_added=false
415
+ local existing_changes_count=0
416
+ local file_ended=false
417
+
418
+ while IFS= read -r line || [[ -n "$line" ]]; do
419
+ # Handle Active Technologies section
420
+ if [[ "$line" == "## Active Technologies" ]]; then
421
+ echo "$line" >> "$temp_file"
422
+ in_tech_section=true
423
+ continue
424
+ elif [[ $in_tech_section == true ]] && [[ "$line" =~ ^##[[:space:]] ]]; then
425
+ # Add new tech entries before closing the section
426
+ if [[ $tech_entries_added == false ]] && [[ ${#new_tech_entries[@]} -gt 0 ]]; then
427
+ printf '%s\n' "${new_tech_entries[@]}" >> "$temp_file"
428
+ tech_entries_added=true
429
+ fi
430
+ echo "$line" >> "$temp_file"
431
+ in_tech_section=false
432
+ continue
433
+ elif [[ $in_tech_section == true ]] && [[ -z "$line" ]]; then
434
+ # Add new tech entries before empty line in tech section
435
+ if [[ $tech_entries_added == false ]] && [[ ${#new_tech_entries[@]} -gt 0 ]]; then
436
+ printf '%s\n' "${new_tech_entries[@]}" >> "$temp_file"
437
+ tech_entries_added=true
438
+ fi
439
+ echo "$line" >> "$temp_file"
440
+ continue
441
+ fi
442
+
443
+ # Handle Recent Changes section
444
+ if [[ "$line" == "## Recent Changes" ]]; then
445
+ echo "$line" >> "$temp_file"
446
+ # Add new change entry right after the heading
447
+ if [[ -n "$new_change_entry" ]]; then
448
+ echo "$new_change_entry" >> "$temp_file"
449
+ fi
450
+ in_changes_section=true
451
+ changes_entries_added=true
452
+ continue
453
+ elif [[ $in_changes_section == true ]] && [[ "$line" =~ ^##[[:space:]] ]]; then
454
+ echo "$line" >> "$temp_file"
455
+ in_changes_section=false
456
+ continue
457
+ elif [[ $in_changes_section == true ]] && [[ "$line" == "- "* ]]; then
458
+ # Keep only first 2 existing changes
459
+ if [[ $existing_changes_count -lt 2 ]]; then
460
+ echo "$line" >> "$temp_file"
461
+ ((existing_changes_count++))
462
+ fi
463
+ continue
464
+ fi
465
+
466
+ # Update timestamp
467
+ if [[ "$line" =~ \*\*Last\ updated\*\*:.*[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] ]]; then
468
+ echo "$line" | sed "s/[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]/$current_date/" >> "$temp_file"
469
+ else
470
+ echo "$line" >> "$temp_file"
471
+ fi
472
+ done < "$target_file"
473
+
474
+ # Post-loop check: if we're still in the Active Technologies section and haven't added new entries
475
+ if [[ $in_tech_section == true ]] && [[ $tech_entries_added == false ]] && [[ ${#new_tech_entries[@]} -gt 0 ]]; then
476
+ printf '%s\n' "${new_tech_entries[@]}" >> "$temp_file"
477
+ tech_entries_added=true
478
+ fi
479
+
480
+ # If sections don't exist, add them at the end of the file
481
+ if [[ $has_active_technologies -eq 0 ]] && [[ ${#new_tech_entries[@]} -gt 0 ]]; then
482
+ echo "" >> "$temp_file"
483
+ echo "## Active Technologies" >> "$temp_file"
484
+ printf '%s\n' "${new_tech_entries[@]}" >> "$temp_file"
485
+ tech_entries_added=true
486
+ fi
487
+
488
+ if [[ $has_recent_changes -eq 0 ]] && [[ -n "$new_change_entry" ]]; then
489
+ echo "" >> "$temp_file"
490
+ echo "## Recent Changes" >> "$temp_file"
491
+ echo "$new_change_entry" >> "$temp_file"
492
+ changes_entries_added=true
493
+ fi
494
+
495
+ # Move temp file to target atomically
496
+ if ! mv "$temp_file" "$target_file"; then
497
+ log_error "Failed to update target file"
498
+ rm -f "$temp_file"
499
+ return 1
500
+ fi
501
+
502
+ return 0
503
+ }
504
+ #==============================================================================
505
+ # Main Agent File Update Function
506
+ #==============================================================================
507
+
508
+ update_agent_file() {
509
+ local target_file="$1"
510
+ local agent_name="$2"
511
+
512
+ if [[ -z "$target_file" ]] || [[ -z "$agent_name" ]]; then
513
+ log_error "update_agent_file requires target_file and agent_name parameters"
514
+ return 1
515
+ fi
516
+
517
+ log_info "Updating $agent_name context file: $target_file"
518
+
519
+ local project_name
520
+ project_name=$(basename "$REPO_ROOT")
521
+ local current_date
522
+ current_date=$(date +%Y-%m-%d)
523
+
524
+ # Create directory if it doesn't exist
525
+ local target_dir
526
+ target_dir=$(dirname "$target_file")
527
+ if [[ ! -d "$target_dir" ]]; then
528
+ if ! mkdir -p "$target_dir"; then
529
+ log_error "Failed to create directory: $target_dir"
530
+ return 1
531
+ fi
532
+ fi
533
+
534
+ if [[ ! -f "$target_file" ]]; then
535
+ # Create new file from template
536
+ local temp_file
537
+ temp_file=$(mktemp) || {
538
+ log_error "Failed to create temporary file"
539
+ return 1
540
+ }
541
+
542
+ if create_new_agent_file "$target_file" "$temp_file" "$project_name" "$current_date"; then
543
+ if mv "$temp_file" "$target_file"; then
544
+ log_success "Created new $agent_name context file"
545
+ else
546
+ log_error "Failed to move temporary file to $target_file"
547
+ rm -f "$temp_file"
548
+ return 1
549
+ fi
550
+ else
551
+ log_error "Failed to create new agent file"
552
+ rm -f "$temp_file"
553
+ return 1
554
+ fi
555
+ else
556
+ # Update existing file
557
+ if [[ ! -r "$target_file" ]]; then
558
+ log_error "Cannot read existing file: $target_file"
559
+ return 1
560
+ fi
561
+
562
+ if [[ ! -w "$target_file" ]]; then
563
+ log_error "Cannot write to existing file: $target_file"
564
+ return 1
565
+ fi
566
+
567
+ if update_existing_agent_file "$target_file" "$current_date"; then
568
+ log_success "Updated existing $agent_name context file"
569
+ else
570
+ log_error "Failed to update existing agent file"
571
+ return 1
572
+ fi
573
+ fi
574
+
575
+ return 0
576
+ }
577
+
578
+ #==============================================================================
579
+ # Agent Selection and Processing
580
+ #==============================================================================
581
+
582
+ update_specific_agent() {
583
+ local agent_type="$1"
584
+
585
+ case "$agent_type" in
586
+ claude)
587
+ update_agent_file "$CLAUDE_FILE" "Claude Code"
588
+ ;;
589
+ gemini)
590
+ update_agent_file "$GEMINI_FILE" "Gemini CLI"
591
+ ;;
592
+ copilot)
593
+ update_agent_file "$COPILOT_FILE" "GitHub Copilot"
594
+ ;;
595
+ cursor-agent)
596
+ update_agent_file "$CURSOR_FILE" "Cursor IDE"
597
+ ;;
598
+ qwen)
599
+ update_agent_file "$QWEN_FILE" "Qwen Code"
600
+ ;;
601
+ opencode)
602
+ update_agent_file "$AGENTS_FILE" "opencode"
603
+ ;;
604
+ codex)
605
+ update_agent_file "$AGENTS_FILE" "Codex CLI"
606
+ ;;
607
+ windsurf)
608
+ update_agent_file "$WINDSURF_FILE" "Windsurf"
609
+ ;;
610
+ kilocode)
611
+ update_agent_file "$KILOCODE_FILE" "Kilo Code"
612
+ ;;
613
+ auggie)
614
+ update_agent_file "$AUGGIE_FILE" "Auggie CLI"
615
+ ;;
616
+ roo)
617
+ update_agent_file "$ROO_FILE" "Roo Code"
618
+ ;;
619
+ codebuddy)
620
+ update_agent_file "$CODEBUDDY_FILE" "CodeBuddy CLI"
621
+ ;;
622
+ qodercli)
623
+ update_agent_file "$QODER_FILE" "Qoder CLI"
624
+ ;;
625
+ amp)
626
+ update_agent_file "$AMP_FILE" "Amp"
627
+ ;;
628
+ shai)
629
+ update_agent_file "$SHAI_FILE" "SHAI"
630
+ ;;
631
+ q)
632
+ update_agent_file "$Q_FILE" "Amazon Q Developer CLI"
633
+ ;;
634
+ agy)
635
+ update_agent_file "$AGY_FILE" "Antigravity"
636
+ ;;
637
+ bob)
638
+ update_agent_file "$BOB_FILE" "IBM Bob"
639
+ ;;
640
+ generic)
641
+ log_info "Generic agent: no predefined context file. Use the agent-specific update script for your agent."
642
+ ;;
643
+ *)
644
+ log_error "Unknown agent type '$agent_type'"
645
+ log_error "Expected: claude|gemini|copilot|cursor-agent|qwen|opencode|codex|windsurf|kilocode|auggie|roo|codebuddy|amp|shai|q|agy|bob|qodercli|generic"
646
+ exit 1
647
+ ;;
648
+ esac
649
+ }
650
+
651
+ update_all_existing_agents() {
652
+ local found_agent=false
653
+
654
+ # Check each possible agent file and update if it exists
655
+ if [[ -f "$CLAUDE_FILE" ]]; then
656
+ update_agent_file "$CLAUDE_FILE" "Claude Code"
657
+ found_agent=true
658
+ fi
659
+
660
+ if [[ -f "$GEMINI_FILE" ]]; then
661
+ update_agent_file "$GEMINI_FILE" "Gemini CLI"
662
+ found_agent=true
663
+ fi
664
+
665
+ if [[ -f "$COPILOT_FILE" ]]; then
666
+ update_agent_file "$COPILOT_FILE" "GitHub Copilot"
667
+ found_agent=true
668
+ fi
669
+
670
+ if [[ -f "$CURSOR_FILE" ]]; then
671
+ update_agent_file "$CURSOR_FILE" "Cursor IDE"
672
+ found_agent=true
673
+ fi
674
+
675
+ if [[ -f "$QWEN_FILE" ]]; then
676
+ update_agent_file "$QWEN_FILE" "Qwen Code"
677
+ found_agent=true
678
+ fi
679
+
680
+ if [[ -f "$AGENTS_FILE" ]]; then
681
+ update_agent_file "$AGENTS_FILE" "Codex/opencode"
682
+ found_agent=true
683
+ fi
684
+
685
+ if [[ -f "$WINDSURF_FILE" ]]; then
686
+ update_agent_file "$WINDSURF_FILE" "Windsurf"
687
+ found_agent=true
688
+ fi
689
+
690
+ if [[ -f "$KILOCODE_FILE" ]]; then
691
+ update_agent_file "$KILOCODE_FILE" "Kilo Code"
692
+ found_agent=true
693
+ fi
694
+
695
+ if [[ -f "$AUGGIE_FILE" ]]; then
696
+ update_agent_file "$AUGGIE_FILE" "Auggie CLI"
697
+ found_agent=true
698
+ fi
699
+
700
+ if [[ -f "$ROO_FILE" ]]; then
701
+ update_agent_file "$ROO_FILE" "Roo Code"
702
+ found_agent=true
703
+ fi
704
+
705
+ if [[ -f "$CODEBUDDY_FILE" ]]; then
706
+ update_agent_file "$CODEBUDDY_FILE" "CodeBuddy CLI"
707
+ found_agent=true
708
+ fi
709
+
710
+ if [[ -f "$SHAI_FILE" ]]; then
711
+ update_agent_file "$SHAI_FILE" "SHAI"
712
+ found_agent=true
713
+ fi
714
+
715
+ if [[ -f "$QODER_FILE" ]]; then
716
+ update_agent_file "$QODER_FILE" "Qoder CLI"
717
+ found_agent=true
718
+ fi
719
+
720
+ if [[ -f "$Q_FILE" ]]; then
721
+ update_agent_file "$Q_FILE" "Amazon Q Developer CLI"
722
+ found_agent=true
723
+ fi
724
+
725
+ if [[ -f "$AGY_FILE" ]]; then
726
+ update_agent_file "$AGY_FILE" "Antigravity"
727
+ found_agent=true
728
+ fi
729
+ if [[ -f "$BOB_FILE" ]]; then
730
+ update_agent_file "$BOB_FILE" "IBM Bob"
731
+ found_agent=true
732
+ fi
733
+
734
+ # If no agent files exist, create a default Claude file
735
+ if [[ "$found_agent" == false ]]; then
736
+ log_info "No existing agent files found, creating default Claude file..."
737
+ update_agent_file "$CLAUDE_FILE" "Claude Code"
738
+ fi
739
+ }
740
+ print_summary() {
741
+ echo
742
+ log_info "Summary of changes:"
743
+
744
+ if [[ -n "$NEW_LANG" ]]; then
745
+ echo " - Added language: $NEW_LANG"
746
+ fi
747
+
748
+ if [[ -n "$NEW_FRAMEWORK" ]]; then
749
+ echo " - Added framework: $NEW_FRAMEWORK"
750
+ fi
751
+
752
+ if [[ -n "$NEW_DB" ]] && [[ "$NEW_DB" != "N/A" ]]; then
753
+ echo " - Added database: $NEW_DB"
754
+ fi
755
+
756
+ echo
757
+
758
+ log_info "Usage: $0 [claude|gemini|copilot|cursor-agent|qwen|opencode|codex|windsurf|kilocode|auggie|roo|codebuddy|amp|shai|q|agy|bob|qodercli]"
759
+ }
760
+
761
+ #==============================================================================
762
+ # Main Execution
763
+ #==============================================================================
764
+
765
+ main() {
766
+ # Validate environment before proceeding
767
+ validate_environment
768
+
769
+ log_info "=== Updating agent context files for feature $CURRENT_BRANCH ==="
770
+
771
+ # Parse the plan file to extract project information
772
+ if ! parse_plan_data "$NEW_PLAN"; then
773
+ log_error "Failed to parse plan data"
774
+ exit 1
775
+ fi
776
+
777
+ # Process based on agent type argument
778
+ local success=true
779
+
780
+ if [[ -z "$AGENT_TYPE" ]]; then
781
+ # No specific agent provided - update all existing agent files
782
+ log_info "No agent specified, updating all existing agent files..."
783
+ if ! update_all_existing_agents; then
784
+ success=false
785
+ fi
786
+ else
787
+ # Specific agent provided - update only that agent
788
+ log_info "Updating specific agent: $AGENT_TYPE"
789
+ if ! update_specific_agent "$AGENT_TYPE"; then
790
+ success=false
791
+ fi
792
+ fi
793
+
794
+ # Print summary
795
+ print_summary
796
+
797
+ if [[ "$success" == true ]]; then
798
+ log_success "Agent context update completed successfully"
799
+ exit 0
800
+ else
801
+ log_error "Agent context update completed with errors"
802
+ exit 1
803
+ fi
804
+ }
805
+
806
+ # Execute main function if script is run directly
807
+ if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
808
+ main "$@"
809
+ fi
810
+
.specify/templates/agent-file-template.md ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # [PROJECT NAME] Development Guidelines
2
+
3
+ Auto-generated from all feature plans. Last updated: [DATE]
4
+
5
+ ## Active Technologies
6
+
7
+ [EXTRACTED FROM ALL PLAN.MD FILES]
8
+
9
+ ## Project Structure
10
+
11
+ ```text
12
+ [ACTUAL STRUCTURE FROM PLANS]
13
+ ```
14
+
15
+ ## Commands
16
+
17
+ [ONLY COMMANDS FOR ACTIVE TECHNOLOGIES]
18
+
19
+ ## Code Style
20
+
21
+ [LANGUAGE-SPECIFIC, ONLY FOR LANGUAGES IN USE]
22
+
23
+ ## Recent Changes
24
+
25
+ [LAST 3 FEATURES AND WHAT THEY ADDED]
26
+
27
+ <!-- MANUAL ADDITIONS START -->
28
+ <!-- MANUAL ADDITIONS END -->
.specify/templates/checklist-template.md ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # [CHECKLIST TYPE] Checklist: [FEATURE NAME]
2
+
3
+ **Purpose**: [Brief description of what this checklist covers]
4
+ **Created**: [DATE]
5
+ **Feature**: [Link to spec.md or relevant documentation]
6
+
7
+ **Note**: This checklist is generated by the `/speckit.checklist` command based on feature context and requirements.
8
+
9
+ <!--
10
+ ============================================================================
11
+ IMPORTANT: The checklist items below are SAMPLE ITEMS for illustration only.
12
+
13
+ The /speckit.checklist command MUST replace these with actual items based on:
14
+ - User's specific checklist request
15
+ - Feature requirements from spec.md
16
+ - Technical context from plan.md
17
+ - Implementation details from tasks.md
18
+
19
+ DO NOT keep these sample items in the generated checklist file.
20
+ ============================================================================
21
+ -->
22
+
23
+ ## [Category 1]
24
+
25
+ - [ ] CHK001 First checklist item with clear action
26
+ - [ ] CHK002 Second checklist item
27
+ - [ ] CHK003 Third checklist item
28
+
29
+ ## [Category 2]
30
+
31
+ - [ ] CHK004 Another category item
32
+ - [ ] CHK005 Item with specific criteria
33
+ - [ ] CHK006 Final item in this category
34
+
35
+ ## Notes
36
+
37
+ - Check items off as completed: `[x]`
38
+ - Add comments or findings inline
39
+ - Link to relevant resources or documentation
40
+ - Items are numbered sequentially for easy reference
.specify/templates/constitution-template.md ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # [PROJECT_NAME] Constitution
2
+ <!-- Example: Spec Constitution, TaskFlow Constitution, etc. -->
3
+
4
+ ## Core Principles
5
+
6
+ ### [PRINCIPLE_1_NAME]
7
+ <!-- Example: I. Library-First -->
8
+ [PRINCIPLE_1_DESCRIPTION]
9
+ <!-- Example: Every feature starts as a standalone library; Libraries must be self-contained, independently testable, documented; Clear purpose required - no organizational-only libraries -->
10
+
11
+ ### [PRINCIPLE_2_NAME]
12
+ <!-- Example: II. CLI Interface -->
13
+ [PRINCIPLE_2_DESCRIPTION]
14
+ <!-- Example: Every library exposes functionality via CLI; Text in/out protocol: stdin/args → stdout, errors → stderr; Support JSON + human-readable formats -->
15
+
16
+ ### [PRINCIPLE_3_NAME]
17
+ <!-- Example: III. Test-First (NON-NEGOTIABLE) -->
18
+ [PRINCIPLE_3_DESCRIPTION]
19
+ <!-- Example: TDD mandatory: Tests written → User approved → Tests fail → Then implement; Red-Green-Refactor cycle strictly enforced -->
20
+
21
+ ### [PRINCIPLE_4_NAME]
22
+ <!-- Example: IV. Integration Testing -->
23
+ [PRINCIPLE_4_DESCRIPTION]
24
+ <!-- Example: Focus areas requiring integration tests: New library contract tests, Contract changes, Inter-service communication, Shared schemas -->
25
+
26
+ ### [PRINCIPLE_5_NAME]
27
+ <!-- Example: V. Observability, VI. Versioning & Breaking Changes, VII. Simplicity -->
28
+ [PRINCIPLE_5_DESCRIPTION]
29
+ <!-- Example: Text I/O ensures debuggability; Structured logging required; Or: MAJOR.MINOR.BUILD format; Or: Start simple, YAGNI principles -->
30
+
31
+ ## [SECTION_2_NAME]
32
+ <!-- Example: Additional Constraints, Security Requirements, Performance Standards, etc. -->
33
+
34
+ [SECTION_2_CONTENT]
35
+ <!-- Example: Technology stack requirements, compliance standards, deployment policies, etc. -->
36
+
37
+ ## [SECTION_3_NAME]
38
+ <!-- Example: Development Workflow, Review Process, Quality Gates, etc. -->
39
+
40
+ [SECTION_3_CONTENT]
41
+ <!-- Example: Code review requirements, testing gates, deployment approval process, etc. -->
42
+
43
+ ## Governance
44
+ <!-- Example: Constitution supersedes all other practices; Amendments require documentation, approval, migration plan -->
45
+
46
+ [GOVERNANCE_RULES]
47
+ <!-- Example: All PRs/reviews must verify compliance; Complexity must be justified; Use [GUIDANCE_FILE] for runtime development guidance -->
48
+
49
+ **Version**: [CONSTITUTION_VERSION] | **Ratified**: [RATIFICATION_DATE] | **Last Amended**: [LAST_AMENDED_DATE]
50
+ <!-- Example: Version: 2.1.1 | Ratified: 2025-06-13 | Last Amended: 2025-07-16 -->
.specify/templates/plan-template.md ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Implementation Plan: [FEATURE]
2
+
3
+ **Branch**: `[###-feature-name]` | **Date**: [DATE] | **Spec**: [link]
4
+ **Input**: Feature specification from `/specs/[###-feature-name]/spec.md`
5
+
6
+ **Note**: This template is filled in by the `/speckit.plan` command. See `.specify/templates/plan-template.md` for the execution workflow.
7
+
8
+ ## Summary
9
+
10
+ [Extract from feature spec: primary requirement + technical approach from research]
11
+
12
+ ## Technical Context
13
+
14
+ <!--
15
+ ACTION REQUIRED: Replace the content in this section with the technical details
16
+ for the project. The structure here is presented in advisory capacity to guide
17
+ the iteration process.
18
+ -->
19
+
20
+ **Language/Version**: [e.g., Python 3.11, Swift 5.9, Rust 1.75 or NEEDS CLARIFICATION]
21
+ **Primary Dependencies**: [e.g., FastAPI, UIKit, LLVM or NEEDS CLARIFICATION]
22
+ **Storage**: [if applicable, e.g., PostgreSQL, CoreData, files or N/A]
23
+ **Testing**: [e.g., pytest, XCTest, cargo test or NEEDS CLARIFICATION]
24
+ **Target Platform**: [e.g., Linux server, iOS 15+, WASM or NEEDS CLARIFICATION]
25
+ **Project Type**: [e.g., library/cli/web-service/mobile-app/compiler/desktop-app or NEEDS CLARIFICATION]
26
+ **Performance Goals**: [domain-specific, e.g., 1000 req/s, 10k lines/sec, 60 fps or NEEDS CLARIFICATION]
27
+ **Constraints**: [domain-specific, e.g., <200ms p95, <100MB memory, offline-capable or NEEDS CLARIFICATION]
28
+ **Scale/Scope**: [domain-specific, e.g., 10k users, 1M LOC, 50 screens or NEEDS CLARIFICATION]
29
+
30
+ ## Constitution Check
31
+
32
+ *GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
33
+
34
+ [Gates determined based on constitution file]
35
+
36
+ ## Project Structure
37
+
38
+ ### Documentation (this feature)
39
+
40
+ ```text
41
+ specs/[###-feature]/
42
+ ├── plan.md # This file (/speckit.plan command output)
43
+ ├── research.md # Phase 0 output (/speckit.plan command)
44
+ ├── data-model.md # Phase 1 output (/speckit.plan command)
45
+ ├── quickstart.md # Phase 1 output (/speckit.plan command)
46
+ ├── contracts/ # Phase 1 output (/speckit.plan command)
47
+ └── tasks.md # Phase 2 output (/speckit.tasks command - NOT created by /speckit.plan)
48
+ ```
49
+
50
+ ### Source Code (repository root)
51
+ <!--
52
+ ACTION REQUIRED: Replace the placeholder tree below with the concrete layout
53
+ for this feature. Delete unused options and expand the chosen structure with
54
+ real paths (e.g., apps/admin, packages/something). The delivered plan must
55
+ not include Option labels.
56
+ -->
57
+
58
+ ```text
59
+ # [REMOVE IF UNUSED] Option 1: Single project (DEFAULT)
60
+ src/
61
+ ├── models/
62
+ ├── services/
63
+ ├── cli/
64
+ └── lib/
65
+
66
+ tests/
67
+ ├── contract/
68
+ ├── integration/
69
+ └── unit/
70
+
71
+ # [REMOVE IF UNUSED] Option 2: Web application (when "frontend" + "backend" detected)
72
+ backend/
73
+ ├── src/
74
+ │ ├── models/
75
+ │ ├── services/
76
+ │ └── api/
77
+ └── tests/
78
+
79
+ frontend/
80
+ ├── src/
81
+ │ ├── components/
82
+ │ ├── pages/
83
+ │ └── services/
84
+ └── tests/
85
+
86
+ # [REMOVE IF UNUSED] Option 3: Mobile + API (when "iOS/Android" detected)
87
+ api/
88
+ └── [same as backend above]
89
+
90
+ ios/ or android/
91
+ └── [platform-specific structure: feature modules, UI flows, platform tests]
92
+ ```
93
+
94
+ **Structure Decision**: [Document the selected structure and reference the real
95
+ directories captured above]
96
+
97
+ ## Complexity Tracking
98
+
99
+ > **Fill ONLY if Constitution Check has violations that must be justified**
100
+
101
+ | Violation | Why Needed | Simpler Alternative Rejected Because |
102
+ |-----------|------------|-------------------------------------|
103
+ | [e.g., 4th project] | [current need] | [why 3 projects insufficient] |
104
+ | [e.g., Repository pattern] | [specific problem] | [why direct DB access insufficient] |
.specify/templates/spec-template.md ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Feature Specification: [FEATURE NAME]
2
+
3
+ **Feature Branch**: `[###-feature-name]`
4
+ **Created**: [DATE]
5
+ **Status**: Draft
6
+ **Input**: User description: "$ARGUMENTS"
7
+
8
+ ## User Scenarios & Testing *(mandatory)*
9
+
10
+ <!--
11
+ IMPORTANT: User stories should be PRIORITIZED as user journeys ordered by importance.
12
+ Each user story/journey must be INDEPENDENTLY TESTABLE - meaning if you implement just ONE of them,
13
+ you should still have a viable MVP (Minimum Viable Product) that delivers value.
14
+
15
+ Assign priorities (P1, P2, P3, etc.) to each story, where P1 is the most critical.
16
+ Think of each story as a standalone slice of functionality that can be:
17
+ - Developed independently
18
+ - Tested independently
19
+ - Deployed independently
20
+ - Demonstrated to users independently
21
+ -->
22
+
23
+ ### User Story 1 - [Brief Title] (Priority: P1)
24
+
25
+ [Describe this user journey in plain language]
26
+
27
+ **Why this priority**: [Explain the value and why it has this priority level]
28
+
29
+ **Independent Test**: [Describe how this can be tested independently - e.g., "Can be fully tested by [specific action] and delivers [specific value]"]
30
+
31
+ **Acceptance Scenarios**:
32
+
33
+ 1. **Given** [initial state], **When** [action], **Then** [expected outcome]
34
+ 2. **Given** [initial state], **When** [action], **Then** [expected outcome]
35
+
36
+ ---
37
+
38
+ ### User Story 2 - [Brief Title] (Priority: P2)
39
+
40
+ [Describe this user journey in plain language]
41
+
42
+ **Why this priority**: [Explain the value and why it has this priority level]
43
+
44
+ **Independent Test**: [Describe how this can be tested independently]
45
+
46
+ **Acceptance Scenarios**:
47
+
48
+ 1. **Given** [initial state], **When** [action], **Then** [expected outcome]
49
+
50
+ ---
51
+
52
+ ### User Story 3 - [Brief Title] (Priority: P3)
53
+
54
+ [Describe this user journey in plain language]
55
+
56
+ **Why this priority**: [Explain the value and why it has this priority level]
57
+
58
+ **Independent Test**: [Describe how this can be tested independently]
59
+
60
+ **Acceptance Scenarios**:
61
+
62
+ 1. **Given** [initial state], **When** [action], **Then** [expected outcome]
63
+
64
+ ---
65
+
66
+ [Add more user stories as needed, each with an assigned priority]
67
+
68
+ ### Edge Cases
69
+
70
+ <!--
71
+ ACTION REQUIRED: The content in this section represents placeholders.
72
+ Fill them out with the right edge cases.
73
+ -->
74
+
75
+ - What happens when [boundary condition]?
76
+ - How does system handle [error scenario]?
77
+
78
+ ## Requirements *(mandatory)*
79
+
80
+ <!--
81
+ ACTION REQUIRED: The content in this section represents placeholders.
82
+ Fill them out with the right functional requirements.
83
+ -->
84
+
85
+ ### Functional Requirements
86
+
87
+ - **FR-001**: System MUST [specific capability, e.g., "allow users to create accounts"]
88
+ - **FR-002**: System MUST [specific capability, e.g., "validate email addresses"]
89
+ - **FR-003**: Users MUST be able to [key interaction, e.g., "reset their password"]
90
+ - **FR-004**: System MUST [data requirement, e.g., "persist user preferences"]
91
+ - **FR-005**: System MUST [behavior, e.g., "log all security events"]
92
+
93
+ *Example of marking unclear requirements:*
94
+
95
+ - **FR-006**: System MUST authenticate users via [NEEDS CLARIFICATION: auth method not specified - email/password, SSO, OAuth?]
96
+ - **FR-007**: System MUST retain user data for [NEEDS CLARIFICATION: retention period not specified]
97
+
98
+ ### Key Entities *(include if feature involves data)*
99
+
100
+ - **[Entity 1]**: [What it represents, key attributes without implementation]
101
+ - **[Entity 2]**: [What it represents, relationships to other entities]
102
+
103
+ ## Success Criteria *(mandatory)*
104
+
105
+ <!--
106
+ ACTION REQUIRED: Define measurable success criteria.
107
+ These must be technology-agnostic and measurable.
108
+ -->
109
+
110
+ ### Measurable Outcomes
111
+
112
+ - **SC-001**: [Measurable metric, e.g., "Users can complete account creation in under 2 minutes"]
113
+ - **SC-002**: [Measurable metric, e.g., "System handles 1000 concurrent users without degradation"]
114
+ - **SC-003**: [User satisfaction metric, e.g., "90% of users successfully complete primary task on first attempt"]
115
+ - **SC-004**: [Business metric, e.g., "Reduce support tickets related to [X] by 50%"]
.specify/templates/tasks-template.md ADDED
@@ -0,0 +1,251 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+
3
+ description: "Task list template for feature implementation"
4
+ ---
5
+
6
+ # Tasks: [FEATURE NAME]
7
+
8
+ **Input**: Design documents from `/specs/[###-feature-name]/`
9
+ **Prerequisites**: plan.md (required), spec.md (required for user stories), research.md, data-model.md, contracts/
10
+
11
+ **Tests**: The examples below include test tasks. Tests are OPTIONAL - only include them if explicitly requested in the feature specification.
12
+
13
+ **Organization**: Tasks are grouped by user story to enable independent implementation and testing of each story.
14
+
15
+ ## Format: `[ID] [P?] [Story] Description`
16
+
17
+ - **[P]**: Can run in parallel (different files, no dependencies)
18
+ - **[Story]**: Which user story this task belongs to (e.g., US1, US2, US3)
19
+ - Include exact file paths in descriptions
20
+
21
+ ## Path Conventions
22
+
23
+ - **Single project**: `src/`, `tests/` at repository root
24
+ - **Web app**: `backend/src/`, `frontend/src/`
25
+ - **Mobile**: `api/src/`, `ios/src/` or `android/src/`
26
+ - Paths shown below assume single project - adjust based on plan.md structure
27
+
28
+ <!--
29
+ ============================================================================
30
+ IMPORTANT: The tasks below are SAMPLE TASKS for illustration purposes only.
31
+
32
+ The /speckit.tasks command MUST replace these with actual tasks based on:
33
+ - User stories from spec.md (with their priorities P1, P2, P3...)
34
+ - Feature requirements from plan.md
35
+ - Entities from data-model.md
36
+ - Endpoints from contracts/
37
+
38
+ Tasks MUST be organized by user story so each story can be:
39
+ - Implemented independently
40
+ - Tested independently
41
+ - Delivered as an MVP increment
42
+
43
+ DO NOT keep these sample tasks in the generated tasks.md file.
44
+ ============================================================================
45
+ -->
46
+
47
+ ## Phase 1: Setup (Shared Infrastructure)
48
+
49
+ **Purpose**: Project initialization and basic structure
50
+
51
+ - [ ] T001 Create project structure per implementation plan
52
+ - [ ] T002 Initialize [language] project with [framework] dependencies
53
+ - [ ] T003 [P] Configure linting and formatting tools
54
+
55
+ ---
56
+
57
+ ## Phase 2: Foundational (Blocking Prerequisites)
58
+
59
+ **Purpose**: Core infrastructure that MUST be complete before ANY user story can be implemented
60
+
61
+ **⚠️ CRITICAL**: No user story work can begin until this phase is complete
62
+
63
+ Examples of foundational tasks (adjust based on your project):
64
+
65
+ - [ ] T004 Setup database schema and migrations framework
66
+ - [ ] T005 [P] Implement authentication/authorization framework
67
+ - [ ] T006 [P] Setup API routing and middleware structure
68
+ - [ ] T007 Create base models/entities that all stories depend on
69
+ - [ ] T008 Configure error handling and logging infrastructure
70
+ - [ ] T009 Setup environment configuration management
71
+
72
+ **Checkpoint**: Foundation ready - user story implementation can now begin in parallel
73
+
74
+ ---
75
+
76
+ ## Phase 3: User Story 1 - [Title] (Priority: P1) 🎯 MVP
77
+
78
+ **Goal**: [Brief description of what this story delivers]
79
+
80
+ **Independent Test**: [How to verify this story works on its own]
81
+
82
+ ### Tests for User Story 1 (OPTIONAL - only if tests requested) ⚠️
83
+
84
+ > **NOTE: Write these tests FIRST, ensure they FAIL before implementation**
85
+
86
+ - [ ] T010 [P] [US1] Contract test for [endpoint] in tests/contract/test_[name].py
87
+ - [ ] T011 [P] [US1] Integration test for [user journey] in tests/integration/test_[name].py
88
+
89
+ ### Implementation for User Story 1
90
+
91
+ - [ ] T012 [P] [US1] Create [Entity1] model in src/models/[entity1].py
92
+ - [ ] T013 [P] [US1] Create [Entity2] model in src/models/[entity2].py
93
+ - [ ] T014 [US1] Implement [Service] in src/services/[service].py (depends on T012, T013)
94
+ - [ ] T015 [US1] Implement [endpoint/feature] in src/[location]/[file].py
95
+ - [ ] T016 [US1] Add validation and error handling
96
+ - [ ] T017 [US1] Add logging for user story 1 operations
97
+
98
+ **Checkpoint**: At this point, User Story 1 should be fully functional and testable independently
99
+
100
+ ---
101
+
102
+ ## Phase 4: User Story 2 - [Title] (Priority: P2)
103
+
104
+ **Goal**: [Brief description of what this story delivers]
105
+
106
+ **Independent Test**: [How to verify this story works on its own]
107
+
108
+ ### Tests for User Story 2 (OPTIONAL - only if tests requested) ⚠️
109
+
110
+ - [ ] T018 [P] [US2] Contract test for [endpoint] in tests/contract/test_[name].py
111
+ - [ ] T019 [P] [US2] Integration test for [user journey] in tests/integration/test_[name].py
112
+
113
+ ### Implementation for User Story 2
114
+
115
+ - [ ] T020 [P] [US2] Create [Entity] model in src/models/[entity].py
116
+ - [ ] T021 [US2] Implement [Service] in src/services/[service].py
117
+ - [ ] T022 [US2] Implement [endpoint/feature] in src/[location]/[file].py
118
+ - [ ] T023 [US2] Integrate with User Story 1 components (if needed)
119
+
120
+ **Checkpoint**: At this point, User Stories 1 AND 2 should both work independently
121
+
122
+ ---
123
+
124
+ ## Phase 5: User Story 3 - [Title] (Priority: P3)
125
+
126
+ **Goal**: [Brief description of what this story delivers]
127
+
128
+ **Independent Test**: [How to verify this story works on its own]
129
+
130
+ ### Tests for User Story 3 (OPTIONAL - only if tests requested) ⚠️
131
+
132
+ - [ ] T024 [P] [US3] Contract test for [endpoint] in tests/contract/test_[name].py
133
+ - [ ] T025 [P] [US3] Integration test for [user journey] in tests/integration/test_[name].py
134
+
135
+ ### Implementation for User Story 3
136
+
137
+ - [ ] T026 [P] [US3] Create [Entity] model in src/models/[entity].py
138
+ - [ ] T027 [US3] Implement [Service] in src/services/[service].py
139
+ - [ ] T028 [US3] Implement [endpoint/feature] in src/[location]/[file].py
140
+
141
+ **Checkpoint**: All user stories should now be independently functional
142
+
143
+ ---
144
+
145
+ [Add more user story phases as needed, following the same pattern]
146
+
147
+ ---
148
+
149
+ ## Phase N: Polish & Cross-Cutting Concerns
150
+
151
+ **Purpose**: Improvements that affect multiple user stories
152
+
153
+ - [ ] TXXX [P] Documentation updates in docs/
154
+ - [ ] TXXX Code cleanup and refactoring
155
+ - [ ] TXXX Performance optimization across all stories
156
+ - [ ] TXXX [P] Additional unit tests (if requested) in tests/unit/
157
+ - [ ] TXXX Security hardening
158
+ - [ ] TXXX Run quickstart.md validation
159
+
160
+ ---
161
+
162
+ ## Dependencies & Execution Order
163
+
164
+ ### Phase Dependencies
165
+
166
+ - **Setup (Phase 1)**: No dependencies - can start immediately
167
+ - **Foundational (Phase 2)**: Depends on Setup completion - BLOCKS all user stories
168
+ - **User Stories (Phase 3+)**: All depend on Foundational phase completion
169
+ - User stories can then proceed in parallel (if staffed)
170
+ - Or sequentially in priority order (P1 → P2 → P3)
171
+ - **Polish (Final Phase)**: Depends on all desired user stories being complete
172
+
173
+ ### User Story Dependencies
174
+
175
+ - **User Story 1 (P1)**: Can start after Foundational (Phase 2) - No dependencies on other stories
176
+ - **User Story 2 (P2)**: Can start after Foundational (Phase 2) - May integrate with US1 but should be independently testable
177
+ - **User Story 3 (P3)**: Can start after Foundational (Phase 2) - May integrate with US1/US2 but should be independently testable
178
+
179
+ ### Within Each User Story
180
+
181
+ - Tests (if included) MUST be written and FAIL before implementation
182
+ - Models before services
183
+ - Services before endpoints
184
+ - Core implementation before integration
185
+ - Story complete before moving to next priority
186
+
187
+ ### Parallel Opportunities
188
+
189
+ - All Setup tasks marked [P] can run in parallel
190
+ - All Foundational tasks marked [P] can run in parallel (within Phase 2)
191
+ - Once Foundational phase completes, all user stories can start in parallel (if team capacity allows)
192
+ - All tests for a user story marked [P] can run in parallel
193
+ - Models within a story marked [P] can run in parallel
194
+ - Different user stories can be worked on in parallel by different team members
195
+
196
+ ---
197
+
198
+ ## Parallel Example: User Story 1
199
+
200
+ ```bash
201
+ # Launch all tests for User Story 1 together (if tests requested):
202
+ Task: "Contract test for [endpoint] in tests/contract/test_[name].py"
203
+ Task: "Integration test for [user journey] in tests/integration/test_[name].py"
204
+
205
+ # Launch all models for User Story 1 together:
206
+ Task: "Create [Entity1] model in src/models/[entity1].py"
207
+ Task: "Create [Entity2] model in src/models/[entity2].py"
208
+ ```
209
+
210
+ ---
211
+
212
+ ## Implementation Strategy
213
+
214
+ ### MVP First (User Story 1 Only)
215
+
216
+ 1. Complete Phase 1: Setup
217
+ 2. Complete Phase 2: Foundational (CRITICAL - blocks all stories)
218
+ 3. Complete Phase 3: User Story 1
219
+ 4. **STOP and VALIDATE**: Test User Story 1 independently
220
+ 5. Deploy/demo if ready
221
+
222
+ ### Incremental Delivery
223
+
224
+ 1. Complete Setup + Foundational → Foundation ready
225
+ 2. Add User Story 1 → Test independently → Deploy/Demo (MVP!)
226
+ 3. Add User Story 2 → Test independently → Deploy/Demo
227
+ 4. Add User Story 3 → Test independently → Deploy/Demo
228
+ 5. Each story adds value without breaking previous stories
229
+
230
+ ### Parallel Team Strategy
231
+
232
+ With multiple developers:
233
+
234
+ 1. Team completes Setup + Foundational together
235
+ 2. Once Foundational is done:
236
+ - Developer A: User Story 1
237
+ - Developer B: User Story 2
238
+ - Developer C: User Story 3
239
+ 3. Stories complete and integrate independently
240
+
241
+ ---
242
+
243
+ ## Notes
244
+
245
+ - [P] tasks = different files, no dependencies
246
+ - [Story] label maps task to specific user story for traceability
247
+ - Each user story should be independently completable and testable
248
+ - Verify tests fail before implementing
249
+ - Commit after each task or logical group
250
+ - Stop at any checkpoint to validate story independently
251
+ - Avoid: vague tasks, same file conflicts, cross-story dependencies that break independence
AGENTS.md ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # AGENTS.md
2
+
3
+ This file provides guidance to coding agents working in this repository.
4
+
5
+ ## Repository Guidelines
6
+
7
+ ### Pipeline-First Development (MANDATORY)
8
+ **All new functionality MUST be implemented as pipeline Steps composed via the Pipeline engine.** Do NOT write standalone scripts, ad-hoc loops, or inline logic that bypasses the pipeline. Before writing any code:
9
+
10
+ 1. Read `docs/design/PIPELINE_DESIGN.md` to understand the Step → Pipeline → Branch model.
11
+ 2. Implement logic as a `Step` class with `requires`/`provides` declarations and a `__call__(self, ctx) -> ctx` method.
12
+ 3. Compose steps using `Pipeline().then(...)` and `.branch(...)` — never manual for-loops or direct function chaining.
13
+ 4. Use `StepContext.replace()` for immutable context updates — never mutate context directly.
14
+ 5. Put integration-specific data in `metadata`, not new context fields, unless the field is shared across multiple pipelines.
15
+
16
+ **Anti-patterns to reject:**
17
+ - Writing a function that calls multiple steps manually instead of composing them in a Pipeline
18
+ - Inline reflection/evaluation logic instead of creating a ReflectStep or EvaluateStep
19
+ - Ad-hoc `ThreadPoolExecutor` usage instead of `async_boundary` and `max_workers` on steps
20
+ - Standalone scripts that duplicate pipeline functionality without using the pipeline engine
21
+ - Bypassing `requires`/`provides` contracts by accessing context fields not declared in `requires`
22
+
23
+ If a task seems like it cannot fit the pipeline model, explain why to the user before proceeding — do not silently circumvent it.
24
+
25
+ ### Core Code Protection
26
+ **Do NOT modify core modules (`ace/core/`, `pipeline/`) without explicit user approval.** Before proposing any change to these directories:
27
+ 1. Read the relevant design docs (`docs/design/ACE_ARCHITECTURE.md`, `docs/design/PIPELINE_DESIGN.md`) thoroughly.
28
+ 2. Evaluate whether the change is truly required or if it can be achieved outside the core (e.g., in an integration, step, or example).
29
+ 3. Clearly explain the proposed change and its justification to the user **before** making any edits.
30
+ 4. Wait for the user to explicitly accept before proceeding.
31
+
32
+ ### Documentation Maintenance
33
+ Before working on code in `ace/`, read `docs/design/ACE_ARCHITECTURE.md` to understand the current architecture.
34
+ Before working on code in `pipeline/` or `ace/core/`, read `docs/design/PIPELINE_DESIGN.md` to understand the pipeline engine.
35
+
36
+ **Docs MUST be kept in sync with code.** Any change that alters a public API, renames a concept, adds/removes a module, or changes execution flow **requires** a corresponding update to the relevant docs. Do not merge code changes that make the documentation inaccurate.
37
+
38
+ Key design docs:
39
+ - `docs/design/ACE_ARCHITECTURE.md` — ACE architecture: layers, core concepts, roles, steps, runners, integrations
40
+ - `docs/design/ACE_REFERENCE.md` — ACE code reference: full implementations, API signatures, usage examples
41
+ - `docs/design/ACE_DECISIONS.md` — design decisions and rejected alternatives (ACE, pipeline, migration)
42
+ - `docs/design/PIPELINE_DESIGN.md` — pipeline engine: steps, StepProtocol, Pipeline, Branch, concurrency
43
+ - If you need to work with collected traces from Logfire, read `agent-guides/logfire.md`
44
+
45
+ ### Project Structure
46
+ - `ace/` — core library: roles (PydanticAI-backed), skillbook, steps, runners, providers, RR, integrations, observability
47
+ - `pipeline/` — generic pipeline engine that `ace` is built on (see `docs/design/PIPELINE_DESIGN.md`)
48
+ - `ace-eval/` — evaluation framework (submodule, separate repo)
49
+ - `tests/` — unit/integration tests (pytest)
50
+ - `examples/` — runnable demos grouped by integration
51
+ - `agent-guides/` — internal development guides for LLM agents; not part of the public docs site
52
+ - `docs/` — guides and reference material
53
+ - `docs/design/ACE_ARCHITECTURE.md` — architecture and concepts (keep in sync with code)
54
+ - `docs/design/ACE_REFERENCE.md` — code reference and examples (keep in sync with code)
55
+ - `docs/design/ACE_DECISIONS.md` — design decisions and rejected alternatives
56
+ - `docs/design/PIPELINE_DESIGN.md` — pipeline engine design doc (keep in sync with code)
57
+
58
+ ### Commands
59
+ - `uv sync` — install all dependencies
60
+ - `uv run pytest` — run tests (coverage enforced `--cov-fail-under=25`)
61
+ - `uv run pytest -m unit` / `-m integration` / `-m slow` — run by marker
62
+ - `uv run black ace/ tests/ examples/` — format code
63
+ - `uv run mypy ace/` — type check
64
+
65
+ ### Coding Style
66
+ - PEP 8 with Black formatting (line length 88)
67
+ - Type hints and docstrings for public APIs
68
+ - Python 3.12 target
69
+ - Test files: `tests/test_*.py`; functions: `test_*`; classes: `Test*`
70
+
71
+ ### Testing
72
+ - Pytest is the primary runner
73
+ - Add tests for new features; include regression tests for bug fixes
74
+
75
+ ### Commits
76
+ - Conventional Commits: `feat(scope): subject`, `fix(scope): subject`
77
+ - Do NOT add `Co-Authored-By` trailers to commit messages
78
+ - PRs should include description, test results, and relevant docs updates
79
+
80
+ ### ACE Roles (quick reference)
81
+
82
+ | Role | Responsibility | Key Class |
83
+ |------|---------------|-----------|
84
+ | **Agent** | Executes tasks using skillbook strategies | `Agent` |
85
+ | **Reflector** | Analyzes execution results | `Reflector` |
86
+ | **SkillManager** | Updates the skillbook with new strategies | `SkillManager` |
87
+
88
+ ### Integration Runners
89
+
90
+ | Runner | Framework | Use Case |
91
+ |--------|-----------|----------|
92
+ | `ACELiteLLM` | LiteLLM (100+ providers) | Simple self-improving agent |
93
+ | `ACELangChain` | LangChain | Wrap chains/agents with learning |
94
+ | `ACEBrowserUse` | browser-use | Browser automation with learning |
95
+ | `ACEClaudeCode` | Claude Code CLI | Coding tasks with learning |
96
+
97
+ NEVER USE FALLBACKS OR IMPLEMENT THINGS I NEVER ASKED FOR.
98
+ IF IT'S STRAIGHFORWARD, IMPLEMENT IT STRAIGHFORWARD.
CHANGELOG.md ADDED
@@ -0,0 +1,445 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Changelog
2
+
3
+ All notable changes to ACE Framework will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.12.0] - 2026-05-06
11
+
12
+ ### Added
13
+ - **Cross-trace generalization gate** for the SkillManager — four-criterion check
14
+ (≥3 instances across ≥2 domains, named slot, no API-specific params in the
15
+ action, verifiable runtime trigger) that constrains when SM may write a broad
16
+ skill subsuming existing narrow ones. Backed by [skill_generalization.md](ace-eval/research/skill_generalization.md)
17
+ (14 cited sources).
18
+ - **Action-equivalence rule** for within-run skill writing — splits on action,
19
+ not on trigger surface. Prevents over-decomposition of structurally identical
20
+ rules.
21
+ - **Atomicity rule** in `insight` formatting — one trigger + one action per
22
+ skill, with explicit good/bad shape examples in the prompt.
23
+ - **Insight format guidance** in the SM prompt sourced from the in-context-
24
+ learning research doc ([icl_skill_formatting.md](ace-eval/research/icl_skill_formatting.md)) — 15-50 word cap, imperative
25
+ voice, positive framing default, examples only for format/shape rules.
26
+ - **Evidence-only tagging** — SM tags only skills the reflection actually
27
+ implicates, instead of iterating over every injected_skill_id.
28
+ - **Broaden-via-comparison rule** for UPDATE — when two skills target the same
29
+ root cause in different niches, broaden `issue` rather than adding a duplicate.
30
+ - **Prompt caching for SM** via `CachePoint(ttl="5m")` mirroring RR's caching;
31
+ cache_read/write tokens forwarded in run metadata.
32
+ - **SM behavior spec + harness** — `ace-eval/scripts/sm_behavior_check.py`,
33
+ `sm_iterative_check.py`, `sm_stability_check.py` and matching scenario
34
+ fixtures cover replay stability, convergence, scope expansion, and the
35
+ below-threshold gate boundary.
36
+
37
+ ### Changed
38
+ - **`update_skills` signature** — `source` is now optional; `SkillbookView`
39
+ was dropped from the parameter list (callers pass the real `Skillbook`
40
+ directly).
41
+ - **Hard removal cap removed** — SM no longer auto-removes skills whose
42
+ `harmful_count >= 3`. Heavily-used skills can legitimately accumulate
43
+ harmful tags without being net-negative; REMOVE now requires explicit
44
+ reflection evidence.
45
+ - **TauBench evaluator** — `evaluation_type=ALL_WITH_NL_ASSERTIONS` on both
46
+ `run_task` and `run_tasks` call sites in
47
+ `ace-eval/src/ace_eval/e2e/benchmarks/tau_bench.py`. Retail (and any future
48
+ benchmark with `NL_ASSERTION` in `reward_basis`) now produces real reward
49
+ numbers instead of crashing on every task during reward computation.
50
+
51
+ ### Removed
52
+ - **Skillbook v1 legacy aliases** on `Skill` and `UpdateOperation` — v2 schema
53
+ is now the only schema.
54
+
55
+ ## [0.11.0] - 2026-04-29
56
+
57
+ ### Added
58
+ - **`RecursiveAgent` core abstraction** — extracted from RR into `ace/core/recursive_agent.py`; provides a generic recursive PydanticAI agent with sandbox, microcompaction, default tool set, and depth-aware sub-agent registration. Reusable across roles beyond the Reflector.
59
+ - **Skillbook v2 schema** — full rewrite of `ace/core/skillbook.py` with section-grouped storage, richer `InsightSource` provenance, and BM25-backed retrieval (`rank-bm25` runtime dependency).
60
+ - **Agentic SkillManager** — `SkillManager` rewritten as a tool-calling loop (`ace/implementations/sm_tools.py`). Provenance is now populated by the SkillManager agent directly rather than a dedicated step.
61
+ - **RR skillbook tools for the Reflector** — Reflector can introspect and propose updates to the skillbook from inside the recursive loop.
62
+ - **Anthropic prompt caching enabled by default** for RR agents; `cache_read_tokens` and `cache_write_tokens` are forwarded in run metadata for cost accounting.
63
+ - **Logfire spans around recursive agent sessions** for end-to-end observability of nested RR runs.
64
+ - **Online / offline mode** in the ACE runner.
65
+ - **`nest-asyncio`** added to the dev extra to support nested loops in notebooks and live test scripts.
66
+
67
+ ### Changed
68
+ - **RR collapsed into a single `RRStep`** — the orchestrator/worker split, batch machinery, and `AttachInsightSourcesStep` have been removed. RR now runs as a true recursive loop with depth-bounded sub-agent delegation and microcompaction of stale tool results.
69
+ - **Reflector prompts** simplified, deduplicated, and made input-agnostic; added early-skillbook-skim and parallel-tool guidance.
70
+ - **`record_observation` tool renamed to `think`** to clarify it is a scratch reasoning channel, not persistent storage.
71
+ - **Native evidence summaries** are produced inside RR before final synthesis.
72
+ - **Skillbook prompt format is now markdown** — `Skillbook.as_prompt()` returns a section-grouped markdown list instead of TOON. The `python-toon` dependency has been dropped.
73
+ - **`metered_model` and `sandbox`** moved from `ace/rr/` into `ace/core/` to reflect their cross-role use.
74
+ - **Pytest defaults** — `uv run pytest` now excludes `integration` and `requires_api` markers by default; coverage flags removed from `addopts` (run with `--cov` explicitly when needed).
75
+ - **Observability** — `tool_arguments` and `tool_response` are no longer scrubbed by the Logfire callback so tool I/O remains inspectable.
76
+
77
+ ### Removed
78
+ - `ace/rr/` legacy package layout (`agent.py`, `runner.py`, `trace_context.py`, `message_trimming.py`, batch helpers). Functionality is now in `ace/core/recursive_agent.py` and `ace/implementations/rr/`.
79
+ - `AttachInsightSourcesStep` and its pipeline wiring — provenance is attached by the SkillManager agent.
80
+ - `python-toon` runtime dependency.
81
+ - TAG handling from the SkillManager.
82
+ - Citation scanning from the Reflector.
83
+
84
+ ## [0.10.0] - 2026-04-13
85
+
86
+ ### Added
87
+ - **Usage metering hook** — `RecursiveConfig.usage_callback: (RequestUsage, model_id) -> None` fires once per pydantic-ai model request (orchestrator turns, sub-agent runs, tool-call follow-ups). Implemented via `ace.rr.MeteredModel`, a `pydantic_ai.models.wrapper.WrapperModel` subclass, so metering lives at the framework's own model boundary — no per-call-site plumbing. Callback exceptions are caught and logged so metering never crashes the pipeline.
88
+ - **Pre-built model instance support** — `RRStep`, `create_rr_agent`, `create_sub_agent`, and `RecursiveConfig.subagent_model` now accept either a model-id string or a pre-built `pydantic_ai.models.Model` instance. Enables callers that need a custom provider (e.g. cross-account Bedrock with STS-assumed credentials) to inject a fully-configured model rather than resolving from a string.
89
+ - **Sub-agent `model_settings`** — `create_sub_agent` now threads an explicit `ModelSettings` parameter into its `PydanticAgent` constructor.
90
+
91
+ ### Notes
92
+ - Back-compat: existing `RRStep(model="...")` callers continue to work unchanged. The widened type signature is additive.
93
+
94
+ ## [0.9.4] - 2026-04-11
95
+
96
+ ### Added
97
+ - **Kayba tracing SDK** — `ace.tracing` module wraps MLflow tracing with Kayba-native configuration, folder organization, and input sanitization (`pip install ace-framework[tracing]`)
98
+
99
+ ## [0.9.3] - 2026-04-01
100
+
101
+ ### Added
102
+ - **Structured design docs** — split ACE_DESIGN.md into architecture, reference, and decisions docs under docs/design/
103
+ - **Simplified Skill model** — removed unused tag counters (helpful/harmful/neutral) and TagStep from the pipeline
104
+ - **Cleaner InsightSource provenance** — restored error_identification and learning_text fields
105
+
106
+ ## [0.9.2] - 2026-03-31
107
+
108
+ ### Added
109
+ - **Insight source provenance** — `InsightSource` typed model captures the origin of each skillbook update (trace ID, sample question, epoch/step, reflection summary, integration metadata); provenance is now populated by the SkillManager agent directly
110
+ - **Claude SDK step** — `ClaudeSDKStep` integration for running Claude Code sub-agents from within ACE pipelines
111
+ - **RR sub-agent code execution** — Recursive Reflector can now delegate to code-execution sub-agents at runtime
112
+ - **RR raw trace batch helpers** — `build_raw_trace_batches` and related runtime utilities for feeding raw traces directly into the RR pipeline
113
+
114
+ ### Fixed
115
+ - **Logfire scrubbing** — added scrubbing callback to stop Logfire over-redacting trace content (reasoning, answers, messages now visible in Logfire UI)
116
+ - **RR combined-batch normalization** — fixed ordering/deduplication of combined task batches in multi-sample runs
117
+
118
+ ### Docs
119
+ - Logfire query API guide clarifications
120
+ - MCP client setup guide and compatibility tests
121
+ - Design docs updated to reflect insight source provenance model
122
+
123
+ ## [0.9.1] - 2026-03-26
124
+
125
+ ### Fixed
126
+ - **CLI packaging** — include .md data files in wheel so `kayba setup` and skill install work on pip/uv-installed packages
127
+
128
+ ## [0.9.0] - 2026-03-26
129
+
130
+ ### Added
131
+ - **PydanticAI migration** — ACE roles (Agent, Reflector, SkillManager) rebuilt on PydanticAI agents with structured output, replacing the legacy role system
132
+ - **Recursive Reflector** — PydanticAI-powered trace analysis agent with sandboxed code execution, sub-agent delegation, and working memory (`save_notes` tool)
133
+ - **Kayba CLI** — full hosted API client with trace upload/management, interactive run, insights, prompts, batch processing, materialization, and integration commands (`kayba` entry point)
134
+
135
+ ## [0.8.8] - 2026-03-17
136
+
137
+ ### Added
138
+ - **Pipeline hooks & cancellation** — `PipelineHook` protocol and `CancellationToken` for observing and controlling pipeline execution
139
+ - **Kayba pipeline skills for Claude Code** — 7-stage dynamic evaluation pipeline that generates custom benchmarks tailored to your agent's domain. Instead of static test suites, the skills analyze your API, build domain-aware metrics and rubrics, create action plans, and run human-in-the-loop validation — all as composable Claude Code skills
140
+ - **`kayba setup` command** — one command to install the full evaluation skill pipeline into your `.claude/skills/` directory, ready to use inside Claude Code out of the box
141
+
142
+ ### Docs
143
+ - Documented `kayba setup` skills installation
144
+
145
+ ### Try it free
146
+ **7-day free trial** — Try the full Kayba evaluation pipeline on our hosted solution with zero setup. Sign up at [kayba.ai](https://kayba.ai) and run `kayba setup` to start building dynamic evals for your agents today.
147
+
148
+ ## [0.8.7] - 2026-03-17
149
+
150
+ ### Added
151
+ - **Improved Opik trace naming** — traces now display the question text (first 80 chars) instead of generic names like "ace_pipeline" or "rr_reflect"
152
+ - **Thread ID support for Opik** — `OpikStep` and `RROpikStep` accept an optional `thread_id` parameter for grouping related traces
153
+
154
+ ## [0.8.5] - 2026-03-04
155
+
156
+ ### Added
157
+ - **Self-contained RR module** (`ace/rr/`) — sandbox, subagent, trace_context, config, code_extraction, message_trimming extracted from `ace/reflector/` into a standalone package
158
+ - **v5.6 prompt promoted as default** — new prompt evolution (v4 → v5.1–v5.6) for the `ace` RR pipeline
159
+ - **`build_steps()` API** — all runners gain a `build_steps()` classmethod for pipeline customization
160
+ - **Shared `CallBudget`** — single budget instance shared across RR pipeline steps
161
+ - **ACE MCP server (optional)** — stdio MCP server in `ace.integrations.mcp` with tools: `ace.ask`, `ace.learn.sample`, `ace.learn.feedback`, `ace.skillbook.get`, `ace.skillbook.save`, `ace.skillbook.load`
162
+ - **Session-scoped state management** — in-memory `session_id` registry with TTL cleanup and per-session async locking
163
+ - **MCP packaging + CLI** — optional `mcp` extra and `ace-mcp` entrypoint
164
+ - **MCP docs and demo client** — integration guide and stdio client example
165
+ - **Composing pipelines guide** — new `docs/guides/composing-pipelines.md`
166
+ - **RR examples** — `rr_demo.py`, `rr_opik_demo.py`, `compose_custom_pipeline.py`
167
+
168
+ ### Changed
169
+ - **RR backward-compat shims** — original `ace/reflector/` files now re-export from `ace.rr` (no duplication)
170
+ - **`RRStep` dual protocol** — implements both `StepProtocol` and `ReflectorLike`
171
+ - **Sandbox hardening** — hardened `getattr` in sandbox execution environment
172
+ - **Opik made opt-in** — moved `opik` from hard dependency to `observability` extra
173
+ - **Safety controls** — runtime request limits (`max_prompt_chars`, `max_samples_per_call`) and optional root-bound path enforcement for save/load via `ACE_MCP_SKILLBOOK_ROOT`
174
+ - **Schema-driven validation** — MCP request/response models aligned to `specs/002-ace-mcp-server/contracts/tool-schemas.md`
175
+ - **`learn_from_feedback` routed through pipeline** — feedback learning now uses the pipeline engine
176
+
177
+ ### Testing
178
+ - Added MCP test suite: models, registry, handlers, and server registration/startup smoke tests
179
+ - Added optional-dependency boundary checks for the MCP integration
180
+ - RR steps at 94%, sandbox at 92%, runner at 74%, MCP models at 100%
181
+
182
+ ## [0.8.4] - 2026-02-27
183
+
184
+ ### Added
185
+ - **OpenClaw integration** — learn from OpenClaw session transcripts (JSONL) via new `OpenClawToTraceStep` and `LoadTracesStep` pipeline steps (#86)
186
+ - **ExportSkillbookMarkdownStep** — export skillbook to markdown file
187
+ - OpenClaw example script and integration docs
188
+
189
+ ## [0.8.3] - 2026-02-21
190
+
191
+ ### Added
192
+ - **Pipeline engine** — generic pipeline framework with branching, async boundaries, and parallel execution (#78)
193
+ - **Trace passthrough** — `_build_traces()` helper and raw trace data passed to RecursiveReflector sandbox
194
+
195
+ ## [0.8.2] - 2026-02-18
196
+
197
+ ### Added
198
+ - **RecursiveReflector None-response guard** — gracefully handles empty/None LLM responses (e.g. from Gemini) with retry prompt instead of crashing
199
+ - **`LiteLLMClient.complete_messages()`** — native multi-turn completion that preserves structured message lists
200
+
201
+ ## [0.8.1] - 2026-02-18
202
+
203
+ ### Added
204
+ - **Insight source tracing** — `InsightSource` dataclass tracks skill provenance (epoch, sample, trace refs, error identification, learning text)
205
+ - **Sample.id** promoted to first-class field with UUID auto-generation
206
+ - **Skillbook query API** — `source_map()`, `source_summary()`, `source_filter()` for skill lineage
207
+ - Insight sources wired through `OfflineACE`, `OnlineACE`, and async learning pipelines
208
+ - `UpdateOperation.learning_index` for linking operations to reflector learnings
209
+ - Bedrock e2e example (`examples/litellm/bedrock_insight_source_test.py`)
210
+ - `docs/INSIGHT_SOURCES.md` guide
211
+
212
+ ## [0.8.0] - 2026-02-17
213
+
214
+ ### Added
215
+ - **Recursive reflector** with sandboxed code execution for validation
216
+ - **TAU-bench integration** with config-driven YAML profiles, prompt sweep, capture/replay, and label support
217
+ - **v3 prompt templates** for agent, reflector, and skill manager roles
218
+ - **Trace context module** exposing agent system prompt and execution context to reflector
219
+
220
+ ### Fixed
221
+ - Opik cloud mode support when `OPIK_API_KEY` is set
222
+ - Bedrock/SageMaker API key lookup skipped for managed providers
223
+ - Reflector trace quality improvements (user messages, turn separators)
224
+
225
+ ### Changed
226
+ - v3 prompts set as default prompt version
227
+ - Reflector now includes agent system prompt in trace context
228
+
229
+ ## [0.7.3] - 2026-02-04
230
+
231
+ ### Added
232
+ - ACE learning for Claude Code via `/ace-learn` (transcript-based learning and skillbook updates).
233
+ - CLI patching to minimize Claude Code system prompt overhead for learning runs.
234
+
235
+ ### Fixed
236
+ - Claude Code transcript parsing for feedback and last-prompt extraction edge cases.
237
+
238
+ ### Changed
239
+ - Unified agent guidance into `AGENTS.md` with `CLAUDE.md` symlink.
240
+
241
+ ## [0.7.0] - 2025-12-04
242
+
243
+ ### ⚠️ Breaking Changes
244
+ - **Complete terminology rename** - Playbook → Skillbook, Bullet → Skill
245
+ - `Playbook` → `Skillbook`
246
+ - `Bullet` → `Skill`
247
+ - `Generator` → `Agent`
248
+ - `Curator` → `SkillManager`
249
+ - `OfflineAdapter` → `OfflineACE`
250
+ - `OnlineAdapter` → `OnlineACE`
251
+ - `DeltaOperation` → `UpdateOperation`
252
+ - `DeltaBatch` → `UpdateBatch`
253
+ - **Migration**: Update imports and method calls to use new names
254
+ - **JSON files**: Change `"bullets"` key to `"skills"` in saved skillbooks
255
+
256
+ ### Added
257
+ - **Deduplication consolidation_operations field** - SkillManagerOutput now properly captures consolidation operations from LLM responses
258
+
259
+ ### Fixed
260
+ - **Deduplication not working** - Added `consolidation_operations` field to SkillManagerOutput Pydantic model. Previously, Instructor was silently dropping these operations.
261
+
262
+ ## [0.5.0] - 2025-11-20
263
+
264
+ ### ⚠️ Breaking Changes
265
+ - **Playbook format changed to TOON (Token-Oriented Object Notation)**
266
+ - `Playbook.as_prompt()` now returns TOON format instead of markdown
267
+ - **Reason**: 16-62% token savings for improved scalability and reduced inference costs
268
+ - **Migration**: No action needed if using playbook with Generator/Curator/Reflector
269
+ - **Debugging**: Use `playbook._as_markdown_debug()` or `str(playbook)` for human-readable output
270
+ - **Details**: Uses tab delimiters and excludes internal metadata (created_at, updated_at)
271
+
272
+ ### Added
273
+ - **ACELiteLLM integration** - Simple conversational agent with automatic learning
274
+ - **ACELangChain integration** - Wrap LangChain Runnables with ACE learning
275
+ - **Custom integration pattern** - Wrap ANY agentic system with ACE learning
276
+ - Base utilities in `ace/integrations/base.py` with `wrap_playbook_context()` helper
277
+ - Complete working example in `examples/custom_integration_example.py`
278
+ - Integration Pattern: Inject playbook → Execute agent → Learn from results
279
+ - **Integration exports** - Import ACEAgent, ACELiteLLM, ACELangChain from `ace` package root
280
+ - **TOON compression for playbooks** - 16-62% token reduction vs markdown
281
+ - **Citation-based tracking** - Strategies cited inline as `[section-00001]`, auto-extracted from reasoning
282
+ - **Enhanced browser traces** - Full execution logs (2200+ chars) passed to Reflector
283
+ - **Test coverage** - Improved from 28% to 70% (241 tests total)
284
+
285
+ ### Changed
286
+ - **Renamed SimpleAgent → ACELiteLLM** - Clearer naming for conversational agent integration
287
+ - `Playbook.__str__()` returns markdown (TOON reserved for LLM consumption via `as_prompt()`)
288
+
289
+ ### Fixed
290
+ - **Browser-use trace integration** - Reflector now receives complete execution traces
291
+ - Fixed initial query duplication (task appeared in both question and reasoning)
292
+ - Fixed missing trace data (reasoning field now contains 2200+ chars vs 154 chars)
293
+ - Fixed screenshot attribute bug causing AttributeError on step.state.screenshot
294
+ - Fixed invalid bullet ID filtering - hallucinated/malformed citations now filtered out
295
+ - Added comprehensive regression tests to catch these issues
296
+ - Impact: Reflector can now properly analyze browser agent's thought process
297
+ - Test coverage improved: 69% → 79% for browser_use.py
298
+ - Prompt v2.1 test assertions updated to match current format
299
+ - All 206 tests now pass (was 189)
300
+
301
+ ## [0.4.0] - 2025-10-26
302
+
303
+ ### Added
304
+ - **Production Observability** with Opik integration
305
+ - Enterprise-grade monitoring and tracing
306
+ - Automatic token usage and cost tracking for all LLM calls
307
+ - Real-time cost monitoring via Opik dashboard
308
+ - Graceful degradation when Opik is not installed
309
+ - **Browser Automation Demos** showing ACE vs baseline performance
310
+ - Domain checker demo with learning capabilities
311
+ - Form filler demo with adaptive strategies
312
+ - Side-by-side comparison of baseline vs ACE-enhanced automation
313
+ - Support for UV package manager (10-100x faster than pip)
314
+ - Added uv.lock for reproducible builds
315
+ - UV-specific installation and development instructions
316
+ - Improved documentation structure with multiple guides
317
+ - QUICK_START.md for 5-minute quickstart
318
+ - API_REFERENCE.md for complete API documentation
319
+ - PROMPT_ENGINEERING.md for advanced techniques
320
+ - SETUP_GUIDE.md for development setup
321
+ - TESTING_GUIDE.md for testing procedures
322
+ - Optional dependency groups for modular installation
323
+ - `observability` for Opik integration
324
+ - `demos` for browser automation examples
325
+ - `langchain` for LangChain support
326
+ - `transformers` for local model support
327
+ - `dev` for development tools
328
+ - `all` for all features combined
329
+
330
+ ### Changed
331
+ - **Replaced explainability module with observability**
332
+ - Removed empty ace/explainability directory
333
+ - Migrated to production-grade Opik monitoring
334
+ - Updated all documentation to reflect this change
335
+ - Improved Python version requirements consistency (3.12 everywhere)
336
+ - Enhanced README with clearer examples and installation options
337
+ - Reorganized examples directory for better discoverability
338
+ - Updated CLAUDE.md with comprehensive codebase guidance
339
+
340
+ ### Fixed
341
+ - Package configuration in pyproject.toml
342
+ - Documentation references to non-existent explainability module
343
+ - Python version inconsistencies across documentation files
344
+
345
+ ### Removed
346
+ - Empty ace/explainability module (replaced by observability)
347
+ - Outdated references to explainability features in documentation
348
+
349
+ ## [0.3.0] - 2025-10-16
350
+
351
+ ### Added
352
+ - **Experimental v2 Prompts** with state-of-the-art prompt engineering
353
+ - Confidence scoring at bullet and answer levels
354
+ - Domain-specific variants for math and code generation
355
+ - Hierarchical structure with identity headers and metadata
356
+ - Concrete examples and anti-patterns for better guidance
357
+ - PromptManager for version control and A/B testing
358
+ - Comprehensive prompt engineering documentation (`docs/PROMPT_ENGINEERING.md`)
359
+ - Advanced examples demonstrating v2 prompts (`examples/advanced_prompts_v2.py`)
360
+ - Comparison script for v1 vs v2 prompts (`examples/compare_v1_v2_prompts.py`)
361
+ - Playbook persistence with `save_to_file()` and `load_from_file()` methods
362
+ - Example demonstrating playbook save/load functionality (`examples/playbook_persistence.py`)
363
+ - py.typed file for PEP 561 type hint support
364
+ - Mermaid flowchart visualization in README showing ACE learning loop
365
+
366
+ ### Changed
367
+ - Enhanced docstrings with comprehensive examples throughout codebase
368
+ - Improved README with v2 prompts section and visual diagrams
369
+ - Updated formatting to comply with Black code style
370
+
371
+ ### Fixed
372
+ - README incorrectly referenced non-existent docs/ directory
373
+ - Test badge URL in README (test.yml → tests.yml)
374
+ - Code formatting issues detected by GitHub Actions
375
+
376
+ ## [0.2.0] - 2025-10-15
377
+
378
+ ### Added
379
+ - LangChain integration via `LangChainLiteLLMClient` for advanced workflows
380
+ - Router support for load balancing across multiple model deployments
381
+ - Comprehensive example for LangChain usage (`examples/langchain_example.py`)
382
+ - Optional installation group: `pip install ace-framework[langchain]`
383
+ - PyPI badges and Quick Links section in README
384
+ - CHANGELOG.md for version tracking
385
+
386
+ ### Fixed
387
+ - Parameter filtering in LiteLLM and LangChain clients (refinement_round, max_refinement_rounds)
388
+ - GitHub Actions workflow using deprecated artifact actions v3 → v4
389
+
390
+ ### Changed
391
+ - Improved README with better structure and badges
392
+ - Updated .gitignore to exclude build artifacts and development files
393
+
394
+ ### Removed
395
+ - Unnecessary development files from repository
396
+
397
+ ## [0.1.1] - 2025-10-15
398
+
399
+ ### Fixed
400
+ - GitHub Actions workflow for PyPI publishing
401
+ - Updated artifact upload/download actions from v3 to v4
402
+
403
+ ## [0.1.0] - 2025-10-15
404
+
405
+ ### Added
406
+ - Initial release of ACE Framework
407
+ - Core ACE implementation based on paper (arXiv:2510.04618)
408
+ - Three-role architecture: Generator, Reflector, and Curator
409
+ - Playbook system for storing and evolving strategies
410
+ - LiteLLM integration supporting 100+ LLM providers
411
+ - Offline and Online adaptation modes
412
+ - Async and streaming support
413
+ - Example scripts for quick start
414
+ - Comprehensive test suite
415
+ - PyPI packaging and GitHub Actions CI/CD
416
+
417
+ ### Features
418
+ - Self-improving agents that learn from experience
419
+ - Delta operations for incremental playbook updates
420
+ - Support for OpenAI, Anthropic, Google, and more via LiteLLM
421
+ - Type hints and modern Python practices
422
+ - MIT licensed for open source use
423
+
424
+ [0.9.4]: https://github.com/Kayba-ai/agentic-context-engine/compare/v0.9.3...v0.9.4
425
+ [0.9.3]: https://github.com/Kayba-ai/agentic-context-engine/compare/v0.9.2...v0.9.3
426
+ [0.9.2]: https://github.com/Kayba-ai/agentic-context-engine/compare/v0.9.1...v0.9.2
427
+ [0.9.1]: https://github.com/Kayba-ai/agentic-context-engine/compare/v0.9.0...v0.9.1
428
+ [0.9.0]: https://github.com/Kayba-ai/agentic-context-engine/compare/v0.8.9...v0.9.0
429
+ [0.8.8]: https://github.com/Kayba-ai/agentic-context-engine/compare/v0.8.7...v0.8.8
430
+ [0.8.7]: https://github.com/Kayba-ai/agentic-context-engine/compare/v0.8.6...v0.8.7
431
+ [0.8.5]: https://github.com/Kayba-ai/agentic-context-engine/compare/v0.8.4...v0.8.5
432
+ [0.8.4]: https://github.com/Kayba-ai/agentic-context-engine/compare/v0.8.3...v0.8.4
433
+ [0.8.3]: https://github.com/Kayba-ai/agentic-context-engine/compare/v0.8.2...v0.8.3
434
+ [0.8.2]: https://github.com/Kayba-ai/agentic-context-engine/compare/v0.8.1...v0.8.2
435
+ [0.8.1]: https://github.com/Kayba-ai/agentic-context-engine/compare/v0.8.0...v0.8.1
436
+ [0.8.0]: https://github.com/Kayba-ai/agentic-context-engine/compare/v0.7.3...v0.8.0
437
+ [0.7.3]: https://github.com/Kayba-ai/agentic-context-engine/compare/v0.7.0...v0.7.3
438
+ [0.7.0]: https://github.com/Kayba-ai/agentic-context-engine/compare/v0.6.0...v0.7.0
439
+ [0.6.0]: https://github.com/Kayba-ai/agentic-context-engine/compare/v0.5.0...v0.6.0
440
+ [0.5.0]: https://github.com/Kayba-ai/agentic-context-engine/compare/v0.4.0...v0.5.0
441
+ [0.4.0]: https://github.com/Kayba-ai/agentic-context-engine/compare/v0.3.0...v0.4.0
442
+ [0.3.0]: https://github.com/Kayba-ai/agentic-context-engine/compare/v0.2.0...v0.3.0
443
+ [0.2.0]: https://github.com/Kayba-ai/agentic-context-engine/compare/v0.1.1...v0.2.0
444
+ [0.1.1]: https://github.com/Kayba-ai/agentic-context-engine/compare/v0.1.0...v0.1.1
445
+ [0.1.0]: https://github.com/Kayba-ai/agentic-context-engine/releases/tag/v0.1.0
CLAUDE.md ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Repository Guidelines
6
+
7
+ ### Pipeline-First Development (MANDATORY)
8
+ **All new functionality MUST be implemented as pipeline Steps composed via the Pipeline engine.** Do NOT write standalone scripts, ad-hoc loops, or inline logic that bypasses the pipeline. Before writing any code:
9
+
10
+ 1. Read `docs/design/PIPELINE_DESIGN.md` to understand the Step → Pipeline → Branch model.
11
+ 2. Implement logic as a `Step` class with `requires`/`provides` declarations and a `__call__(self, ctx) -> ctx` method.
12
+ 3. Compose steps using `Pipeline().then(...)` and `.branch(...)` — never manual for-loops or direct function chaining.
13
+ 4. Use `StepContext.replace()` for immutable context updates — never mutate context directly.
14
+ 5. Put integration-specific data in `metadata`, not new context fields, unless the field is shared across multiple pipelines.
15
+
16
+ **Anti-patterns to reject:**
17
+ - Writing a function that calls multiple steps manually instead of composing them in a Pipeline
18
+ - Inline reflection/evaluation logic instead of creating a ReflectStep or EvaluateStep
19
+ - Ad-hoc `ThreadPoolExecutor` usage instead of `async_boundary` and `max_workers` on steps
20
+ - Standalone scripts that duplicate pipeline functionality without using the pipeline engine
21
+ - Bypassing `requires`/`provides` contracts by accessing context fields not declared in `requires`
22
+
23
+ If a task seems like it cannot fit the pipeline model, explain why to the user before proceeding — do not silently circumvent it.
24
+
25
+ ### Core Code Protection
26
+ **Do NOT modify core modules (`ace/core/`, `pipeline/`) without explicit user approval.** Before proposing any change to these directories:
27
+ 1. Read the relevant design docs (`docs/design/ACE_ARCHITECTURE.md`, `docs/design/PIPELINE_DESIGN.md`) thoroughly.
28
+ 2. Evaluate whether the change is truly required or if it can be achieved outside the core (e.g., in an integration, step, or example).
29
+ 3. Clearly explain the proposed change and its justification to the user **before** making any edits.
30
+ 4. Wait for the user to explicitly accept before proceeding.
31
+
32
+ ### Documentation Maintenance
33
+ Before working on code in `ace/`, read `docs/design/ACE_ARCHITECTURE.md` to understand the current architecture.
34
+ Before working on code in `pipeline/` or `ace/core/`, read `docs/design/PIPELINE_DESIGN.md` to understand the pipeline engine.
35
+
36
+ **Docs MUST be kept in sync with code.** Any change that alters a public API, renames a concept, adds/removes a module, or changes execution flow **requires** a corresponding update to the relevant docs. Do not merge code changes that make the documentation inaccurate.
37
+
38
+ Key design docs:
39
+ - `docs/design/ACE_ARCHITECTURE.md` — ACE architecture: layers, core concepts, roles, steps, runners, integrations
40
+ - `docs/design/ACE_REFERENCE.md` — ACE code reference: full implementations, API signatures, usage examples
41
+ - `docs/design/ACE_DECISIONS.md` — design decisions and rejected alternatives (ACE, pipeline, migration)
42
+ - `docs/design/PIPELINE_DESIGN.md` — pipeline engine: steps, StepProtocol, Pipeline, Branch, concurrency
43
+ - If you need to work with collected traces from Logfire, read `agent-guides/logfire.md`
44
+
45
+ ### Project Structure
46
+ - `ace/` — core library: roles (PydanticAI-backed), skillbook, steps, runners, providers, RR, integrations, observability
47
+ - `pipeline/` — generic pipeline engine that `ace` is built on (see `docs/design/PIPELINE_DESIGN.md`)
48
+ - `ace-eval/` — evaluation framework (submodule, separate repo)
49
+ - `tests/` — unit/integration tests (pytest)
50
+ - `examples/` — runnable demos grouped by integration
51
+ - `agent-guides/` — internal development guides for LLM agents; not part of the public docs site
52
+ - `docs/` — guides and reference material
53
+ - `docs/design/ACE_ARCHITECTURE.md` — architecture and concepts (keep in sync with code)
54
+ - `docs/design/ACE_REFERENCE.md` — code reference and examples (keep in sync with code)
55
+ - `docs/design/ACE_DECISIONS.md` — design decisions and rejected alternatives
56
+ - `docs/design/PIPELINE_DESIGN.md` — pipeline engine design doc (keep in sync with code)
57
+
58
+ ### Commands
59
+ - `uv sync` — install all dependencies
60
+ - `uv run pytest` — run tests (excludes `integration` and `requires_api` markers by default)
61
+ - `uv run pytest -m unit` / `-m integration` / `-m slow` — run by marker
62
+ - `uv run black ace/ tests/ examples/` — format code
63
+ - `uv run mypy ace/` — type check
64
+
65
+ ### Coding Style
66
+ - PEP 8 with Black formatting (line length 88)
67
+ - Type hints and docstrings for public APIs
68
+ - Python 3.12 target
69
+ - Test files: `tests/test_*.py`; functions: `test_*`; classes: `Test*`
70
+
71
+ ### Testing
72
+ - Pytest is the primary runner
73
+ - Add tests for new features; include regression tests for bug fixes
74
+
75
+ ### Commits
76
+ - Conventional Commits: `feat(scope): subject`, `fix(scope): subject`
77
+ - Do NOT add `Co-Authored-By` trailers to commit messages
78
+ - PRs should include description, test results, and relevant docs updates
79
+
80
+ ### ACE Roles (quick reference)
81
+
82
+ | Role | Responsibility | Key Class |
83
+ |------|---------------|-----------|
84
+ | **Agent** | Executes tasks using skillbook strategies | `Agent` |
85
+ | **Reflector** | Analyzes execution results | `Reflector` |
86
+ | **SkillManager** | Updates the skillbook with new strategies | `SkillManager` |
87
+
88
+ ### Integration Runners
89
+
90
+ | Runner | Framework | Use Case |
91
+ |--------|-----------|----------|
92
+ | `ACELiteLLM` | LiteLLM (100+ providers) | Simple self-improving agent |
93
+ | `ACELangChain` | LangChain | Wrap chains/agents with learning |
94
+ | `ACEBrowserUse` | browser-use | Browser automation with learning |
95
+ | `ACEClaudeCode` | Claude Code CLI | Coding tasks with learning |
96
+
97
+ NEVER USE FALLBACKS OR IMPLEMENT THINGS I NEVER ASKED FOR.
98
+
99
+ Keep your answers concise and to the point. If you don't know something, say you don't know instead of making assumptions or fabricating information. Always ask clarifying questions if the user's request is ambiguous or lacks necessary details.
CONTRIBUTING.md ADDED
@@ -0,0 +1,183 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ **By submitting a pull request to this repository, you agree to the terms below.**
2
+
3
+ ## Contributor Terms
4
+
5
+ (a) The contribution is your original work and you have the right to submit it.
6
+ (b) You license your contribution under the project's current license (Apache-2.0).
7
+ (c) You grant the maintainers the right to relicense your contribution as part of the project under any future open-source or commercial license.
8
+
9
+ ---
10
+
11
+ # Contributing to ACE Framework
12
+
13
+ Thank you for your interest in contributing to the Agentic Context Engine! We welcome contributions from the community.
14
+
15
+ ## How to Contribute
16
+
17
+ ### Reporting Bugs
18
+
19
+ Before creating bug reports, please check existing issues to avoid duplicates. When creating a bug report, include:
20
+
21
+ - A clear and descriptive title
22
+ - Steps to reproduce the issue
23
+ - Expected behavior vs actual behavior
24
+ - Environment details (OS, Python version, package versions)
25
+ - Any relevant error messages or logs
26
+
27
+ ### Suggesting Enhancements
28
+
29
+ Enhancement suggestions are welcome! Please provide:
30
+
31
+ - A clear description of the enhancement
32
+ - Use cases and benefits
33
+ - Possible implementation approach (optional)
34
+ - Any potential drawbacks or considerations
35
+
36
+ ### Pull Requests
37
+
38
+ 1. Fork the repository
39
+ 2. Create a feature branch (`git checkout -b feature/amazing-feature`)
40
+ 3. Make your changes
41
+ 4. Run tests to ensure nothing breaks
42
+ 5. Commit your changes using conventional commits (see below)
43
+ 6. Push to your branch
44
+ 7. Open a Pull Request
45
+
46
+ ## Branch Naming Convention
47
+
48
+ Use consistent prefixes for branch names:
49
+
50
+ | Prefix | Purpose | Example |
51
+ |--------|---------|---------|
52
+ | `feature/` | New features | `feature/john/benchmarks` |
53
+ | `fix/` | Bug fixes | `fix/jane/memory-leak` |
54
+ | `docs/` | Documentation changes | `docs/john/api-reference` |
55
+ | `refactor/` | Code refactoring | `refactor/jane/llm-client` |
56
+ | `test/` | Test additions/fixes | `test/john/integration-suite` |
57
+ | `chore/` | Maintenance tasks | `chore/jane/update-deps` |
58
+
59
+ **Format:** `<type>/<developer>/<description>`
60
+
61
+ **Rules:**
62
+ - Use lowercase with hyphens (kebab-case)
63
+ - Use your GitHub username or first name as developer identifier
64
+ - Keep descriptions short but descriptive
65
+ - Include issue number if applicable: `fix/john/123-login-error`
66
+ - Never push directly to `main` - always use feature branches
67
+
68
+ ## Worktree Workflow
69
+
70
+ We use git worktrees to work on multiple branches simultaneously without switching. Each branch gets its own directory.
71
+
72
+ ### Claude Code Commands
73
+
74
+ | Command | Description | Example |
75
+ |---------|-------------|---------|
76
+ | `/create-branch` | Create branch + worktree | `/create-branch feature add-caching` |
77
+ | `/checkout-branch` | Switch to branch (creates worktree if needed) | `/checkout-branch add-caching` |
78
+ | `/list-branches` | List branches with worktree status | `/list-branches` or `/list-branches feature` |
79
+ | `/remove-branch` | Remove branch + worktree | `/remove-branch feature/john/add-caching` |
80
+
81
+ ### Worktree Path Convention
82
+
83
+ Worktrees are created as siblings to the main worktree:
84
+ - Branch: `feature/john/add-caching`
85
+ - Worktree: `../feature-john-add-caching`
86
+
87
+ ### Manual Worktree Commands
88
+
89
+ ```bash
90
+ # List all worktrees
91
+ git worktree list
92
+
93
+ # Add worktree for existing branch
94
+ git worktree add ../path-name branch-name
95
+
96
+ # Add worktree with new branch
97
+ git worktree add -b new-branch ../path-name
98
+
99
+ # Remove worktree
100
+ git worktree remove ../path-name
101
+
102
+ # Prune stale worktree references
103
+ git worktree prune
104
+ ```
105
+
106
+ ### Benefits
107
+
108
+ - **Parallel development**: Work on multiple features without stashing
109
+ - **Faster context switching**: No need to rebuild dependencies
110
+ - **Cleaner git history**: No accidental commits to wrong branch
111
+ - **IDE-friendly**: Open each worktree in separate IDE windows
112
+
113
+ ## Development Setup
114
+
115
+ ```bash
116
+ # Clone your fork
117
+ git clone https://github.com/your-username/agentic-context-engine.git
118
+ cd agentic-context-engine
119
+
120
+ # Install all dependencies (uses UV - 10-100x faster than pip)
121
+ uv sync
122
+
123
+ # Run tests
124
+ uv run pytest
125
+
126
+ # Run linting and formatting
127
+ uv run black ace/ tests/ examples/
128
+ uv run mypy ace/
129
+
130
+ # Run specific test files
131
+ uv run pytest tests/test_skillbook.py
132
+ uv run pytest -m unit # Only unit tests
133
+ uv run pytest -m integration # Only integration tests
134
+ ```
135
+
136
+ ## Commit Message Format
137
+
138
+ We use [Conventional Commits](https://www.conventionalcommits.org/) for clear commit history and automatic changelog generation.
139
+
140
+ Format: `<type>(<scope>): <subject>`
141
+
142
+ Types:
143
+ - `feat`: New feature
144
+ - `fix`: Bug fix
145
+ - `docs`: Documentation only
146
+ - `style`: Code style changes (formatting, etc.)
147
+ - `refactor`: Code refactoring
148
+ - `test`: Adding tests
149
+ - `chore`: Maintenance tasks
150
+
151
+ Examples:
152
+ ```
153
+ feat(llm): add support for new LLM provider
154
+ fix(adapter): resolve memory leak in online mode
155
+ docs(readme): update installation instructions
156
+ ```
157
+
158
+ ## Code Style
159
+
160
+ - Follow PEP 8
161
+ - Use type hints where possible
162
+ - Add docstrings to all public functions and classes
163
+ - Keep line length under 100 characters
164
+ - Use Black for automatic formatting
165
+
166
+ ## Testing
167
+
168
+ - Write tests for new features
169
+ - Ensure all tests pass before submitting PR
170
+ - Aim for good test coverage
171
+ - Use meaningful test names
172
+
173
+ ## Documentation
174
+
175
+ - Update README.md if adding new features
176
+ - Add docstrings to new code
177
+ - Update CHANGELOG.md following Keep a Changelog format
178
+ - Include examples for new functionality
179
+
180
+ ## Questions?
181
+
182
+ Feel free to open an issue for any questions or join the discussion in [GitHub Discussions](https://github.com/Kayba-ai/agentic-context-engine/discussions).
183
+
Dockerfile CHANGED
@@ -1,19 +1,20 @@
1
- FROM mcr.microsoft.com/playwright:v1.44.0-jammy
2
 
3
  WORKDIR /app
4
 
5
- # Install python and pip
6
- RUN apt-get update && apt-get install -y python3 python3-pip && rm -rf /var/lib/apt/lists/*
7
 
8
- COPY requirements.txt .
9
- RUN pip3 install --no-cache-dir -r requirements.txt
10
 
11
- # Install playwright browsers
12
- RUN pip3 install playwright
13
- RUN playwright install chromium
14
-
15
- COPY . .
16
 
17
  EXPOSE 7860
18
 
 
19
  CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7860"]
 
1
+ FROM python:3.10-slim
2
 
3
  WORKDIR /app
4
 
5
+ # Install uv for fast dependency resolution as recommended by ACE
6
+ RUN pip install uv
7
 
8
+ # Copy the ACE repository and our FastAPI files
9
+ COPY . /app
10
 
11
+ # Install ACE framework using uv (referencing the local pyproject.toml in the cloned repo)
12
+ # and install FastAPI components
13
+ RUN uv pip install --system fastapi uvicorn pydantic litellm
14
+ # Since the cloned directory has pyproject.toml, we can install the local package
15
+ RUN uv pip install --system -e .
16
 
17
  EXPOSE 7860
18
 
19
+ # We need the user to pass API keys in Space Secrets (e.g. OPENAI_API_KEY, GROQ_API_KEY)
20
  CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7860"]
LICENSE ADDED
@@ -0,0 +1,201 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "[]"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright [yyyy] [name of copyright owner]
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
README.md CHANGED
@@ -1,10 +1,224 @@
1
- ---
2
- title: Logic Engine
3
- emoji: 🏃
4
- colorFrom: indigo
5
- colorTo: yellow
6
- sdk: docker
7
- pinned: false
8
- ---
9
-
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <a href="https://kayba.ai"><img src="assets/kayba-banner.png" alt="Kayba - Stop fixing agents by hand" width="1080"/></a>
2
+
3
+ # Agentic Context Engine (ACE)
4
+
5
+ [![GitHub stars](https://img.shields.io/github/stars/kayba-ai/agentic-context-engine)](https://github.com/kayba-ai/agentic-context-engine/stargazers)
6
+ [![Kayba Website](https://img.shields.io/badge/kayba.ai-6B8BA8?style=flat&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAIpElEQVR42q1XbWwU1xU9d2Z29sPe2V3jyHVwDNixkiBiqKKixA1IBloKCRJSAaU4ip0PhaiJE0JSqSU/WqlpihpXiaJGmJBGSiGOEj4MjsuHhDApENzEjYHaxTbGJUUuBsvaHXt3vbuzM6c/1l6MvW7+5EpPu/t23rvnnvfm3HsFgArAzsvLu1/TtF+SrAYQBKDguzUHgCkipyyRHfFI5AIAVQDA7/evE5E9IhIgp64hAJmxkwggItmRWUOQhENmliHXPpx4nmMiUmuaZrPk5+cvVBSlQ0S8JNMZRkRy7AIRgaqqsG0HyWQCqVQKjuMAABRFhdutw+32QASwbWcagOwXW0Q0kilFUX6giai/FsGkc23agqypqoZ02oJpmvB6vZi/YAHmlZaisLAQiqJgeHgYl/v7MTAwADoODMOAoigTAGVyTwGgkUyLiO44zm/EMIxhEZlDZh+YGvOEcxWmGUEwGMRjjz2GjRs2YunSpfDl+QAAdtrG+Pg4TNPEpUuX0PTxxzh48ADGx8fh9XpBTg9IKAI4pCmGYSQAceekHAJFVRCJRLB27Vq8/tvXseT7SwAAHR0dOHz4MDo6OnD9+nVYloX8vHyUlZdhcWUlUpaF5uZm9Pf3Q1XV20BM3AMASMMwjIRhGMw1CgoKCIAvvPACU8kkSXJgYIBPPPEEjUCAE7zmHHPvnMuqqioWFRXR7/czEAjk8mHlYCBzXpqmIRwOY9OmTfho70eZqP/RgdraWvT29kJEcN999+Ghhx7C3eV3w+P1IBwOo7u7G+3t7RgcHITH44HH44HjOFOjnmqTDExFF2AwGKTP5+OCBQt47T/XmE6n2dXVxbvuuosAWFRUxIaGBl7/73VONytlsedSD7dt20afz8f8/HwGg0HOwrKV8wgmqX/zD2+SJGPRGNesWUMALCkpYVtbW8ZZ0mLn151sOdzC5uZmfvXlV4xFY1kwB/YfoGEY/w/ETACBQID5+fksKvoeey71kCT/2tpKXdfpdru55y97SJKdX3dy3bp1LCwspNvtpsfjYUFBAVetXMVjx44xmcjcmU8++YS6rjMQCOS6BzMBhEIhqqrKVatWMRaN0bEdPv/z5wmA1dXVTCaT7LnUw7KysuyF03WdiqJQRKhpGl0uF3fu3EkrZZEkt2/fTgAsKCiYAUDJpXa2baOsrAxerxfxeBy9vb0AgJUrV0LXdTT8sQEDAwNYvXo1PvjgA5xqO4VDzYewefNmuN1ueDwe1NfX48jRIwCBl7e+jIULFyIej0NRbnc5A8DkTfX7/RBFkEgmYI6aAICysjKMjY7h+PHjCAaD8Pv9OHToEHa9twv33HMP9u7di3f/9C5EFOi6jtdeew1DQ0MovKMQGzdsRCKR+BYAItB1HQBgmqMgCU3VsnNpK40rV67gxtANkMT+/fvR0tKCDz/8EFU/rMKXf/8StXW12PLss4jH4+jq6kJ7ezsIoqqqCrquZ1/JaQAyE4oIysvLoaoqLvf1IRaNId+fj/KycgDAyZMnYaUtpO00HMfBli1b8NRTTyMUCmFkZASNjY2wbRt1dXV46623cPGfF7Fi5Qok4gnMmz8PwWAQ6XQ6NwMiAsuyUFFRgVAohPMXzqPvch9UVcVP1qyBoggOHDyIM2fOYHHlYgQCATQ2NuLP77+PQCCQAd1/GclEEqXzSrF582ZcvHARra2tUDUNXo8XPq8vmz1nAFBVBfF4HEVFRaioqIBpmmhqagIAPPLIWvxo1Y8xNjaKhoYGpFIpjIyMYPuvtuPVX7yKSCQCkiicUwiPx4NIOILly5bh8ccfR9vJNui6C8lkElbauo1+AMgqYSiUEZ8n657kG797I/vanD1zliTZ19vHBx54gACy77yqqnS5XPR6vdQ0jUePHKVlWezu6mZxcTEB8J133iFJfvHFOfr9fhq360FGBwJGZtLn87G0tJSdX3eyoqKCIsJFixbx6r+vkiSvXbvG+vp6FhcXU9O07CiZO5d79+xlOp1mdCzK8fFxfvPNN3zmmWfYfq6dJLl79+4pWjAdwASqSQne1biLx48dnxAZN5csWcLzneezEtvb08sD+/fzvV3vsampiVf6rzCVSDEei7OpqYnLli1jS0sLk8kkw+Ew01aa69evp6IoDIVCMwFkJiaSUF4eS0pKaEZM7vj9DgKg2+1mcXEx3377bd68cZO5LBaNcWRkhPfee282ZwxcGaBt2zz9t9P0+Xy55PgWA4ZxiwUR4aZNm0iSO3bsoMfjoaIoVFWVlfdX8qWXXmLjzkZevXqVfX193Lp1Kx999FFGo1Hu3r2bJXNL2H6unalkhpXq6mpqmjYRvTEbAzOz4SvbXiFJtp1s44MPPkiXy3Vb0XH69GmeOHEi+/u5555jMplkV1cXU4kU6ZAv1r84Wx6YPR0bgQBDoRABsK62jqlkiiS579N9rKmp4eLFi+n3+/n5qc957tw5lpeXs6amhvs+3cdwOELHdhiPxTPORaaf+1QWcgEITMmMGSYqKyv5Wctn2fMeGxtjd3c3BwcHOTw8zBtDN7L/2WmbZ8+e5YoVKwhgFuczSjK4Z2tnNE1DNBqF4zhYvnw5Nvx0Ax5++GHMnz8fLpcLJGFZFgYHB3HhwgUcOnwYra2tSCTGEQgEZkjv9JJMDMMYBmTOlLp9Sh2f+VQUFQAxNjYG27YRDIZw553FKCgogCIKRsdGMXR9CDeHb8JxCMMwoKoKbNuezTEBAemMimEY+0Rkw63GRHI2JoBAVRVABGkrDctKZaNTFBW67oLL5co0gY6TqwCdaraIqCRbJC8vb5Gqqh0i4r7Vmk1nYmbRckvTJdsXfovTyZbLmXBuichSJRaLdYnIz0hGRUTL9IXIycAkLpKgQziOA8exp0Q8y9Jb8zLhPCYiNaZpnlcBqMlk8l8ej+cYyTkA7gCgT6L9DocNIAzgqIg8bZrmCQDq/wBcV6BSGdN3ewAAAABJRU5ErkJggg==&logoColor=white)](https://kayba.ai)
7
+ [![Discord](https://img.shields.io/discord/1429935408145236131?label=Discord&logo=discord&logoColor=white&color=5865F2)](https://discord.gg/mqCqH7sTyK)
8
+ [![Twitter Follow](https://img.shields.io/twitter/follow/kaybaai?style=social)](https://twitter.com/kaybaai)
9
+ [![Documentation](https://img.shields.io/badge/docs-latest-blue.svg)](https://kayba-ai.github.io/agentic-context-engine/latest/)
10
+
11
+ > [!TIP]
12
+ > ACE is the open-source engine behind [Kayba](https://kayba.ai). If you'd rather have the whole loop managed for you, from failure investigation to fixes shipped as PRs, [get a demo](https://kayba.ai).
13
+
14
+ ---
15
+
16
+ **AI agents don't learn from experience.** They repeat the same mistakes every session, forget what worked, and ignore what failed. ACE is the open-source engine that adds a persistent learning loop. It also powers [Kayba](https://kayba.ai), the managed service that does this for your production agents automatically.
17
+
18
+ <img src="examples/seahorse-emoji-ace.gif" alt="ACE learns from mistakes in real time" width="70%"/>
19
+
20
+ > The agent claims a seahorse emoji exists. ACE reflects on the error, and on the next attempt, the agent responds correctly — without human intervention.
21
+
22
+ ---
23
+
24
+ ## Proven Results
25
+
26
+ | Metric | Result | Context |
27
+ |:-------|:-------|:--------|
28
+ | **2x consistency** | Doubles pass^4 on Tau2 airline benchmark | 15 learned strategies, no reward signals |
29
+ | **49% token reduction** | Browser automation costs cut nearly in half | 10-run learning curve |
30
+ | **$1.50 learning cost** | Claude Code translated 14k lines to TypeScript | Zero build errors, all tests passing |
31
+
32
+ ---
33
+
34
+ ## Quick Start
35
+
36
+ ```bash
37
+ uv add ace-framework
38
+ ```
39
+
40
+ **Option A** — Interactive setup (recommended):
41
+
42
+ ```bash
43
+ ace setup # Walks you through model selection, API keys, and connection validation
44
+ ```
45
+
46
+ **Option B** — Manual configuration:
47
+
48
+ ```bash
49
+ export OPENAI_API_KEY="your-key" # or ANTHROPIC_API_KEY, or any of 100+ supported providers
50
+ ```
51
+
52
+ Then use it:
53
+
54
+ ```python
55
+ from ace import ACELiteLLM
56
+
57
+ agent = ACELiteLLM(model="gpt-4o-mini")
58
+
59
+ # First attempt — the agent may hallucinate
60
+ answer = agent.ask("Is there a seahorse emoji?")
61
+
62
+ # Feed a correction — ACE extracts a strategy and updates the Skillbook
63
+ agent.learn_from_feedback("There is no seahorse emoji in Unicode.")
64
+
65
+ # Subsequent calls benefit from the learned strategy
66
+ answer = agent.ask("Is there a seahorse emoji?")
67
+
68
+ # Inspect what the agent has learned
69
+ print(agent.get_strategies())
70
+ ```
71
+
72
+ No fine-tuning, no training data, no vector database.
73
+
74
+ [-> Quick Start Guide](https://kayba-ai.github.io/agentic-context-engine/latest/getting-started/quick-start/) | [-> Setup Guide](https://kayba-ai.github.io/agentic-context-engine/latest/getting-started/setup/) | [-> Hosted API: Where Do Traces Come From?](https://kayba-ai.github.io/agentic-context-engine/latest/integrations/hosted-api/#where-do-traces-come-from)
75
+
76
+ ---
77
+
78
+ ## How It Works
79
+
80
+ ACE maintains a **Skillbook** — a persistent collection of strategies that evolves with every task. Three specialized roles manage the learning loop:
81
+
82
+ | Role | Responsibility |
83
+ |:-----|:---------------|
84
+ | **Agent** | Executes tasks, enhanced with Skillbook strategies |
85
+ | **Reflector** | Analyzes execution traces to extract what worked and what failed |
86
+ | **SkillManager** | Curates the Skillbook — adds, refines, and removes strategies |
87
+
88
+ The **Recursive Reflector** is the key innovation: instead of summarizing traces in a single pass, it writes and executes Python code in a sandboxed environment to programmatically search for patterns, isolate errors, and iterate until it finds actionable insights.
89
+
90
+ ```mermaid
91
+ flowchart LR
92
+ Skillbook[(Skillbook)]
93
+ Start([Task]) --> Agent[Agent]
94
+ Agent <--> Environment[Environment]
95
+ Environment -- Trace --> Reflector[Reflector]
96
+ Reflector --> SkillManager[SkillManager]
97
+ SkillManager -- Updates --> Skillbook
98
+ Skillbook -. Strategies .-> Agent
99
+ ```
100
+
101
+ All roles are backed by [PydanticAI](https://ai.pydantic.dev/) agents with structured output validation. PydanticAI routes to 100+ LLM providers through its LiteLLM integration, with native support for OpenAI, Anthropic, Google, Bedrock, Groq, and more.
102
+
103
+ *Based on the [ACE paper](https://arxiv.org/abs/2510.04618) (Stanford & SambaNova) and [Dynamic Cheatsheet](https://arxiv.org/abs/2504.07952).*
104
+
105
+ ---
106
+
107
+ ## Runners
108
+
109
+ | Runner | Class | Description |
110
+ |:-------|:------|:------------|
111
+ | **LiteLLM** | `ACELiteLLM` | Batteries-included agent with `.ask()`, `.learn()`, `.save()` — accepts any [LiteLLM model string](https://docs.litellm.ai/docs/providers) |
112
+ | **Core** | `ACE` | Full learning loop with batch epochs and evaluation |
113
+ | **Trace Analyser** | `TraceAnalyser` | Learn from pre-recorded traces without re-running tasks |
114
+ | **browser-use** | `BrowserUse` | Browser automation that improves with each run |
115
+ | **LangChain** | `LangChain` | Wrap any LangChain chain or agent with learning |
116
+ | **Claude Code** | `ClaudeCode` | Claude Code CLI tasks with learning |
117
+
118
+ ```bash
119
+ uv add 'ace-framework[browser-use]' # Browser automation
120
+ uv add 'ace-framework[langchain]' # LangChain
121
+ uv add 'ace-framework[logfire]' # Observability (auto-instruments PydanticAI)
122
+ uv add 'ace-framework[mcp]' # MCP server for IDE integration
123
+ uv add 'ace-framework[deduplication]' # Embedding-based skill deduplication
124
+ ```
125
+
126
+ Have existing agent logs? Extract strategies from them directly:
127
+
128
+ ```python
129
+ from ace import ACELiteLLM
130
+
131
+ agent = ACELiteLLM(model="gpt-4o-mini")
132
+ agent.learn_from_traces(your_existing_traces)
133
+ print(agent.get_strategies())
134
+ ```
135
+
136
+ [-> Examples](examples/)
137
+
138
+ ---
139
+
140
+ ## Benchmarks
141
+
142
+ ### Tau2 — Multi-Step Agentic Tasks
143
+
144
+ [tau2-bench](https://github.com/sierra-research/tau2-bench) by Sierra Research: airline domain tasks requiring tool use and policy adherence. Claude Haiku 4.5 agent, strategies learned on the train split with no reward signals, evaluated on the held-out test split.
145
+
146
+ <img src="benchmarks/tasks/tau_bench/Tau2Benchmark Result Haiku4.5.png" alt="Tau2 Benchmark — ACE doubles consistency at pass^4" width="35%"/>
147
+
148
+ *pass^k = probability all k independent attempts succeed. ACE doubles consistency at pass^4 with 15 learned strategies.*
149
+
150
+ ### Claude Code — Autonomous Translation
151
+
152
+ ACE + Claude Code translated this library from Python to TypeScript with zero supervision:
153
+
154
+ | Metric | Result |
155
+ |:-------|:-------|
156
+ | Duration | ~4 hours |
157
+ | Commits | 119 |
158
+ | Lines written | ~14,000 |
159
+ | Build errors | 0 |
160
+ | Tests | All passing |
161
+ | Learning cost | ~$1.50 |
162
+
163
+ ---
164
+
165
+ ## Pipeline Architecture
166
+
167
+ ACE is built on a composable pipeline engine. Each step declares what it requires and what it produces:
168
+
169
+ ```
170
+ AgentStep -> EvaluateStep -> ReflectStep -> UpdateStep -> DeduplicateStep
171
+ ```
172
+
173
+ Use `learning_tail()` for the standard learning sequence, or compose custom pipelines:
174
+
175
+ ```python
176
+ from ace import Pipeline, AgentStep, EvaluateStep, learning_tail
177
+
178
+ steps = [AgentStep(agent, skillbook), EvaluateStep(env)] + learning_tail(reflector, skill_manager, skillbook)
179
+ pipeline = Pipeline(steps)
180
+ ```
181
+
182
+ The pipeline engine ([`pipeline/`](pipeline/)) is framework-agnostic with `requires`/`provides` contracts, immutable context, and error isolation. See [Pipeline Design](docs/design/PIPELINE_DESIGN.md) and [Architecture](docs/design/ACE_ARCHITECTURE.md).
183
+
184
+ ---
185
+
186
+ ## CLI
187
+
188
+ | Command | Description |
189
+ |:--------|:------------|
190
+ | `ace setup` | Interactive setup — model selection, API keys, connection validation |
191
+ | `ace models <query>` | Search available models with pricing |
192
+ | `ace validate <model>` | Test a model connection |
193
+ | `ace config` | Show current configuration |
194
+ | `kayba` | Cloud CLI — upload traces, fetch insights, manage prompts |
195
+ | `ace-mcp` | MCP server for IDE integration |
196
+
197
+ ---
198
+
199
+ ## Documentation
200
+
201
+ - [Full Documentation](https://kayba-ai.github.io/agentic-context-engine/latest/) — Guides, API reference, examples
202
+ - [Quick Start](https://kayba-ai.github.io/agentic-context-engine/latest/getting-started/quick-start/) — 5-minute setup
203
+ - [Setup Guide](https://kayba-ai.github.io/agentic-context-engine/latest/getting-started/setup/) — Configuration and providers
204
+ - [Hosted API Guide](https://kayba-ai.github.io/agentic-context-engine/latest/integrations/hosted-api/) — Hosted CLI, trace upload, prompt install
205
+ - [Architecture](docs/design/ACE_ARCHITECTURE.md) — Core concepts and system design
206
+ - [Code Reference](docs/design/ACE_REFERENCE.md) — Implementations, API, usage examples
207
+ - [Design Decisions](docs/design/ACE_DECISIONS.md) — Rejected alternatives and rationale
208
+ - [Pipeline Engine](docs/design/PIPELINE_DESIGN.md) — Step composition and context flow
209
+ - [Examples](examples/) — Runnable demos
210
+ - [Changelog](CHANGELOG.md) — Version history
211
+
212
+ ---
213
+
214
+ ## Contributing
215
+
216
+ Contributions are welcome. See [Contributing Guidelines](CONTRIBUTING.md).
217
+
218
+ ---
219
+
220
+ <div align="center">
221
+
222
+ **Built by [Kayba](https://kayba.ai) and the open-source community.**
223
+
224
+ </div>
ace.toml ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ [default]
2
+ model = "us.writer.palmyra-x5-v1:0"
ace/__init__.py ADDED
@@ -0,0 +1,197 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """ACE — Agentic Context Engine.
2
+
3
+ All public symbols are lazily imported to keep ``import ace`` fast.
4
+ Direct attribute access (``ace.ACE``, ``from ace import ACE``)
5
+ works — the underlying module is loaded on first use.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from typing import TYPE_CHECKING
11
+
12
+ if TYPE_CHECKING:
13
+ # Static analysis / IDE autocomplete — never executed at runtime.
14
+ from pipeline import Branch, MergeStrategy, Pipeline, SampleResult, StepProtocol
15
+
16
+ from .core import (
17
+ ACEStepContext,
18
+ EnvironmentResult,
19
+ InsightSource,
20
+ Sample,
21
+ SimpleEnvironment,
22
+ Skill,
23
+ Skillbook,
24
+ SkillbookView,
25
+ TaskEnvironment,
26
+ TraceIdentity,
27
+ UpdateBatch,
28
+ UpdateOperation,
29
+ )
30
+ from .deduplication import DeduplicationManager, SimilarityDetector
31
+ from .implementations import Agent, Reflector, SkillManager
32
+ from .integrations import wrap_skillbook_context
33
+ from .protocols import DeduplicationConfig
34
+ from .providers import ACEModelConfig, ModelConfig
35
+ from .steps.rr_step import RRConfig, RRStep
36
+ from .tracing import configure as configure_tracing
37
+ from .runners import (
38
+ ACE,
39
+ ACELiteLLM,
40
+ ACERunner,
41
+ BrowserUse,
42
+ ClaudeCode,
43
+ LangChain,
44
+ TraceAnalyser,
45
+ )
46
+ from .steps import (
47
+ AgentStep,
48
+ CheckpointStep,
49
+ DeduplicateStep,
50
+ EvaluateStep,
51
+ ExportSkillbookMarkdownStep,
52
+ LoadTracesStep,
53
+ ObservabilityStep,
54
+ PersistStep,
55
+ ReflectStep,
56
+ UpdateStep,
57
+ learning_tail,
58
+ )
59
+
60
+ # ---- lazy import mapping: name -> (module_path, attribute) ----------------
61
+
62
+ _LAZY_IMPORTS: dict[str, tuple[str, str]] = {
63
+ # Pipeline engine (re-exported from pipeline/)
64
+ "Pipeline": ("pipeline", "Pipeline"),
65
+ "Branch": ("pipeline", "Branch"),
66
+ "MergeStrategy": ("pipeline", "MergeStrategy"),
67
+ "StepProtocol": ("pipeline", "StepProtocol"),
68
+ "SampleResult": ("pipeline", "SampleResult"),
69
+ # ACE context
70
+ "ACEStepContext": ("ace.core", "ACEStepContext"),
71
+ "SkillbookView": ("ace.core", "SkillbookView"),
72
+ # Core data types
73
+ "InsightSource": ("ace.core", "InsightSource"),
74
+ "Skill": ("ace.core", "Skill"),
75
+ "Skillbook": ("ace.core", "Skillbook"),
76
+ "TraceIdentity": ("ace.core", "TraceIdentity"),
77
+ "UpdateOperation": ("ace.core", "UpdateOperation"),
78
+ "UpdateBatch": ("ace.core", "UpdateBatch"),
79
+ "Sample": ("ace.core", "Sample"),
80
+ "EnvironmentResult": ("ace.core", "EnvironmentResult"),
81
+ "TaskEnvironment": ("ace.core", "TaskEnvironment"),
82
+ "SimpleEnvironment": ("ace.core", "SimpleEnvironment"),
83
+ # Implementations
84
+ "Agent": ("ace.implementations", "Agent"),
85
+ "Reflector": ("ace.implementations", "Reflector"),
86
+ "SkillManager": ("ace.implementations", "SkillManager"),
87
+ # Deduplication
88
+ "DeduplicationConfig": ("ace.protocols", "DeduplicationConfig"),
89
+ "DeduplicationManager": ("ace.deduplication", "DeduplicationManager"),
90
+ "SimilarityDetector": ("ace.deduplication", "SimilarityDetector"),
91
+ # Integrations
92
+ "wrap_skillbook_context": ("ace.integrations", "wrap_skillbook_context"),
93
+ # Config
94
+ "ModelConfig": ("ace.providers", "ModelConfig"),
95
+ "ACEModelConfig": ("ace.providers", "ACEModelConfig"),
96
+ # Runners
97
+ "ACE": ("ace.runners", "ACE"),
98
+ "ACELiteLLM": ("ace.runners", "ACELiteLLM"),
99
+ "ACERunner": ("ace.runners", "ACERunner"),
100
+ "BrowserUse": ("ace.runners", "BrowserUse"),
101
+ "ClaudeCode": ("ace.runners", "ClaudeCode"),
102
+ "LangChain": ("ace.runners", "LangChain"),
103
+ "TraceAnalyser": ("ace.runners", "TraceAnalyser"),
104
+ # Steps
105
+ "AgentStep": ("ace.steps", "AgentStep"),
106
+ "EvaluateStep": ("ace.steps", "EvaluateStep"),
107
+ "ReflectStep": ("ace.steps", "ReflectStep"),
108
+ "UpdateStep": ("ace.steps", "UpdateStep"),
109
+ "DeduplicateStep": ("ace.steps", "DeduplicateStep"),
110
+ "CheckpointStep": ("ace.steps", "CheckpointStep"),
111
+ "LoadTracesStep": ("ace.steps", "LoadTracesStep"),
112
+ "ExportSkillbookMarkdownStep": ("ace.steps", "ExportSkillbookMarkdownStep"),
113
+ "ObservabilityStep": ("ace.steps", "ObservabilityStep"),
114
+ "PersistStep": ("ace.steps", "PersistStep"),
115
+ "learning_tail": ("ace.steps", "learning_tail"),
116
+ # Recursive Reflector
117
+ "RRStep": ("ace.steps.rr_step", "RRStep"),
118
+ "RRConfig": ("ace.steps.rr_step", "RRConfig"),
119
+ # Tracing
120
+ "configure_tracing": ("ace.tracing", "configure"),
121
+ }
122
+
123
+
124
+ def __getattr__(name: str) -> object:
125
+ if name in _LAZY_IMPORTS:
126
+ module_path, attr = _LAZY_IMPORTS[name]
127
+ import importlib
128
+
129
+ module = importlib.import_module(module_path)
130
+ value = getattr(module, attr)
131
+ # Cache on the module so __getattr__ is only called once per name.
132
+ globals()[name] = value
133
+ return value
134
+ raise AttributeError(f"module 'ace' has no attribute {name!r}")
135
+
136
+
137
+ __all__ = [
138
+ # Pipeline composition
139
+ "Pipeline",
140
+ "Branch",
141
+ "MergeStrategy",
142
+ "StepProtocol",
143
+ "SampleResult",
144
+ # ACE context
145
+ "ACEStepContext",
146
+ "SkillbookView",
147
+ # Core data types
148
+ "InsightSource",
149
+ "Skill",
150
+ "Skillbook",
151
+ "TraceIdentity",
152
+ "UpdateOperation",
153
+ "UpdateBatch",
154
+ # Environments
155
+ "Sample",
156
+ "EnvironmentResult",
157
+ "TaskEnvironment",
158
+ "SimpleEnvironment",
159
+ # Implementations
160
+ "Agent",
161
+ "Reflector",
162
+ "SkillManager",
163
+ # Config
164
+ "ModelConfig",
165
+ "ACEModelConfig",
166
+ # Runners
167
+ "ACE",
168
+ "ACELiteLLM",
169
+ "ACERunner",
170
+ "BrowserUse",
171
+ "ClaudeCode",
172
+ "LangChain",
173
+ "TraceAnalyser",
174
+ # Steps
175
+ "AgentStep",
176
+ "EvaluateStep",
177
+ "ReflectStep",
178
+ "UpdateStep",
179
+ "DeduplicateStep",
180
+ "CheckpointStep",
181
+ "LoadTracesStep",
182
+ "ExportSkillbookMarkdownStep",
183
+ "ObservabilityStep",
184
+ "PersistStep",
185
+ "learning_tail",
186
+ # Recursive Reflector
187
+ "RRStep",
188
+ "RRConfig",
189
+ # Deduplication
190
+ "DeduplicationConfig",
191
+ "DeduplicationManager",
192
+ "SimilarityDetector",
193
+ # Tracing
194
+ "configure_tracing",
195
+ # Utilities
196
+ "wrap_skillbook_context",
197
+ ]
ace/cli/__init__.py ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Kayba CLI."""
2
+
3
+ import click
4
+
5
+ from ace.cli.cloud import (
6
+ upload,
7
+ traces,
8
+ run,
9
+ insights,
10
+ prompts,
11
+ status,
12
+ materialize,
13
+ batch,
14
+ setup,
15
+ integrations,
16
+ )
17
+
18
+
19
+ @click.group()
20
+ @click.version_option(package_name="ace-framework")
21
+ def cli():
22
+ """Kayba CLI."""
23
+ pass
24
+
25
+
26
+ cli.add_command(upload)
27
+ cli.add_command(traces)
28
+ cli.add_command(run)
29
+ cli.add_command(insights)
30
+ cli.add_command(prompts)
31
+ cli.add_command(status)
32
+ cli.add_command(materialize)
33
+ cli.add_command(batch)
34
+ cli.add_command(setup)
35
+ cli.add_command(integrations)
36
+
37
+
38
+ def main():
39
+ cli()
ace/cli/client.py ADDED
@@ -0,0 +1,310 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """HTTP client for the Kayba hosted API."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import os
7
+ import re
8
+ from typing import Any, Dict, List, Optional
9
+
10
+
11
+ class KaybaAPIError(Exception):
12
+ """Structured error from the Kayba API."""
13
+
14
+ def __init__(self, code: str, message: str, status_code: int = 0):
15
+ self.code = code
16
+ self.message = message
17
+ self.status_code = status_code
18
+ super().__init__(f"[{code}] {message}")
19
+
20
+
21
+ DEFAULT_BASE_URL = "https://use.kayba.ai/api"
22
+ MAX_TRACE_UPLOAD_BODY_BYTES = 900_000
23
+
24
+
25
+ def _chunk_trace_uploads(
26
+ traces: List[Dict[str, Any]],
27
+ ) -> List[List[Dict[str, Any]]]:
28
+ """Split uploads into request-sized batches under the body size cap."""
29
+ batches: List[List[Dict[str, Any]]] = []
30
+ current: List[Dict[str, Any]] = []
31
+ current_size = len('{"traces":[]}')
32
+
33
+ for trace in traces:
34
+ trace_size = len(
35
+ json.dumps(trace, ensure_ascii=False, separators=(",", ":")).encode(
36
+ "utf-8"
37
+ )
38
+ )
39
+ separator_size = 1 if current else 0
40
+ candidate_size = current_size + separator_size + trace_size
41
+
42
+ if current and candidate_size > MAX_TRACE_UPLOAD_BODY_BYTES:
43
+ batches.append(current)
44
+ current = [trace]
45
+ current_size = len('{"traces":[]}') + trace_size
46
+ continue
47
+
48
+ current.append(trace)
49
+ current_size = candidate_size
50
+
51
+ if current:
52
+ batches.append(current)
53
+
54
+ return batches
55
+
56
+
57
+ class KaybaClient:
58
+ """HTTP client for the Kayba hosted API.
59
+
60
+ Args:
61
+ api_key: Kayba API key. Falls back to KAYBA_API_KEY env var.
62
+ base_url: API base URL. Falls back to KAYBA_API_URL env var,
63
+ then to https://use.kayba.ai/api.
64
+ """
65
+
66
+ def __init__(
67
+ self,
68
+ api_key: Optional[str] = None,
69
+ base_url: Optional[str] = None,
70
+ ):
71
+ try:
72
+ import requests
73
+ except ImportError as exc:
74
+ raise KaybaAPIError(
75
+ "DEPENDENCY_MISSING",
76
+ "The hosted Kayba CLI requires the cloud extra. Install with "
77
+ "`uv add \"ace-framework[cloud]\"` or "
78
+ "`pip install 'ace-framework[cloud]'`.",
79
+ ) from exc
80
+
81
+ self.api_key = api_key or os.environ.get("KAYBA_API_KEY", "")
82
+ if not self.api_key:
83
+ raise KaybaAPIError(
84
+ "AUTH_MISSING",
85
+ "No API key provided. Set KAYBA_API_KEY or pass --api-key.",
86
+ )
87
+ self.base_url = (
88
+ base_url or os.environ.get("KAYBA_API_URL") or DEFAULT_BASE_URL
89
+ ).rstrip("/")
90
+ self.session: Any = requests.Session()
91
+ self.session.headers["Authorization"] = f"Bearer {self.api_key}"
92
+
93
+ @staticmethod
94
+ def _summarize_http_body(body: str, limit: int = 240) -> str:
95
+ """Collapse whitespace so raw HTML and proxy errors stay readable."""
96
+ snippet = re.sub(r"\s+", " ", body or "").strip()
97
+ if not snippet:
98
+ return "Unexpected non-JSON error from the Kayba API."
99
+ if len(snippet) <= limit:
100
+ return snippet
101
+ return snippet[: limit - 3] + "..."
102
+
103
+ def _request(
104
+ self,
105
+ method: str,
106
+ path: str,
107
+ *,
108
+ json: Optional[Dict[str, Any]] = None,
109
+ params: Optional[Dict[str, str]] = None,
110
+ ) -> Any:
111
+ """Send a request and return parsed JSON, raising on API errors."""
112
+ url = f"{self.base_url}{path}"
113
+ resp = self.session.request(method, url, json=json, params=params)
114
+
115
+ if resp.status_code >= 400:
116
+ try:
117
+ body = resp.json()
118
+ err = body.get("error", {})
119
+ if isinstance(err, str):
120
+ raise KaybaAPIError(
121
+ code="API_ERROR",
122
+ message=err,
123
+ status_code=resp.status_code,
124
+ )
125
+ message = err.get("message", resp.text)
126
+ if (
127
+ resp.status_code == 413
128
+ or "maximum content size" in message.lower()
129
+ or "too large" in message.lower()
130
+ ):
131
+ raise KaybaAPIError(
132
+ code="PAYLOAD_TOO_LARGE",
133
+ message=message,
134
+ status_code=resp.status_code,
135
+ )
136
+ raise KaybaAPIError(
137
+ code=err.get("code", "UNKNOWN"),
138
+ message=message,
139
+ status_code=resp.status_code,
140
+ )
141
+ except (ValueError, KeyError, AttributeError):
142
+ message = self._summarize_http_body(resp.text)
143
+ if resp.status_code == 413:
144
+ message = (
145
+ "Upload rejected because the request body is too large. "
146
+ "Try smaller traces or upload fewer files at once."
147
+ )
148
+ elif resp.status_code in (401, 403):
149
+ message = "Authentication failed; check KAYBA_API_KEY"
150
+ else:
151
+ message = f"HTTP {resp.status_code} from Kayba API: {message}"
152
+ raise KaybaAPIError(
153
+ code="HTTP_ERROR",
154
+ message=message,
155
+ status_code=resp.status_code,
156
+ )
157
+
158
+ if resp.status_code == 204:
159
+ return {}
160
+ return resp.json()
161
+
162
+ # -- Traces --
163
+
164
+ def upload_traces(self, traces: List[Dict[str, Any]]) -> Dict[str, Any]:
165
+ """Upload trace files.
166
+
167
+ Args:
168
+ traces: List of dicts with keys: filename, content, fileType.
169
+ """
170
+ batches = _chunk_trace_uploads(traces)
171
+ if len(batches) == 1:
172
+ return self._request("POST", "/traces", json={"traces": traces})
173
+
174
+ combined: Dict[str, Any] = {"count": 0, "traces": []}
175
+ for batch in batches:
176
+ result = self._request("POST", "/traces", json={"traces": batch})
177
+ uploaded = result.get("traces", [])
178
+ combined["count"] += result.get("count", len(uploaded) or len(batch))
179
+ combined["traces"].extend(uploaded)
180
+ for key, value in result.items():
181
+ if key not in {"count", "traces"} and key not in combined:
182
+ combined[key] = value
183
+ return combined
184
+
185
+ def list_traces(self) -> Dict[str, Any]:
186
+ """List all traces (metadata only, no content)."""
187
+ return self._request("GET", "/traces")
188
+
189
+ def get_trace(self, trace_id: str) -> Dict[str, Any]:
190
+ """Get a single trace with full content."""
191
+ return self._request("GET", f"/traces/{trace_id}")
192
+
193
+ def get_traces(self, trace_ids: List[str]) -> Dict[str, Any]:
194
+ """Batch get traces by IDs (with content)."""
195
+ return self._request("POST", "/traces/batch", json={"ids": trace_ids})
196
+
197
+ def delete_trace(self, trace_id: str) -> Dict[str, Any]:
198
+ """Delete a single trace."""
199
+ return self._request("DELETE", f"/traces/{trace_id}")
200
+
201
+ def delete_traces(self, trace_ids: List[str]) -> Dict[str, Any]:
202
+ """Delete multiple traces."""
203
+ results = []
204
+ errors = []
205
+ for tid in trace_ids:
206
+ try:
207
+ self.delete_trace(tid)
208
+ results.append(tid)
209
+ except KaybaAPIError as e:
210
+ errors.append({"id": tid, "error": str(e)})
211
+ return {"deleted": results, "errors": errors}
212
+
213
+ # -- Insights --
214
+
215
+ def generate_insights(
216
+ self,
217
+ *,
218
+ trace_ids: Optional[List[str]] = None,
219
+ model: Optional[str] = None,
220
+ epochs: Optional[int] = None,
221
+ reflector_mode: Optional[str] = None,
222
+ anthropic_key: Optional[str] = None,
223
+ ) -> Dict[str, Any]:
224
+ """Start async insight generation."""
225
+ body: Dict[str, Any] = {}
226
+ if trace_ids:
227
+ body["traceIds"] = trace_ids
228
+ if model:
229
+ body["model"] = model
230
+ if epochs is not None:
231
+ body["epochs"] = epochs
232
+ if reflector_mode:
233
+ body["reflectorMode"] = reflector_mode
234
+ if anthropic_key:
235
+ body["anthropicApiKey"] = anthropic_key
236
+ return self._request("POST", "/insights/generate", json=body)
237
+
238
+ def list_insights(
239
+ self,
240
+ *,
241
+ status: Optional[str] = None,
242
+ section: Optional[str] = None,
243
+ ) -> Dict[str, Any]:
244
+ """List insights, optionally filtered."""
245
+ params: Dict[str, str] = {}
246
+ if status:
247
+ params["status"] = status
248
+ if section:
249
+ params["section"] = section
250
+ return self._request("GET", "/insights", params=params or None)
251
+
252
+ def triage_insight(
253
+ self,
254
+ insight_id: str,
255
+ status: str,
256
+ note: Optional[str] = None,
257
+ ) -> Dict[str, Any]:
258
+ """Accept or reject a single insight."""
259
+ body: Dict[str, Any] = {"status": status}
260
+ if note:
261
+ body["note"] = note
262
+ return self._request("PATCH", f"/insights/{insight_id}", json=body)
263
+
264
+ # -- Jobs --
265
+
266
+ def get_job(self, job_id: str) -> Dict[str, Any]:
267
+ """Get job status."""
268
+ return self._request("GET", f"/jobs/{job_id}")
269
+
270
+ def materialize_job(self, job_id: str) -> Dict[str, Any]:
271
+ """Materialize completed job results into the skillbook."""
272
+ return self._request("POST", f"/jobs/{job_id}")
273
+
274
+ # -- Prompts --
275
+
276
+ def generate_prompt(
277
+ self,
278
+ *,
279
+ insight_ids: Optional[List[str]] = None,
280
+ label: Optional[str] = None,
281
+ ) -> Dict[str, Any]:
282
+ """Generate a prompt from accepted insights."""
283
+ body: Dict[str, Any] = {}
284
+ if insight_ids:
285
+ body["insightIds"] = insight_ids
286
+ if label:
287
+ body["label"] = label
288
+ return self._request("POST", "/prompts/generate", json=body)
289
+
290
+ def list_prompts(self) -> Dict[str, Any]:
291
+ """List all prompt versions."""
292
+ return self._request("GET", "/prompts")
293
+
294
+ def get_prompt(self, prompt_id: str) -> Dict[str, Any]:
295
+ """Get a specific prompt by ID."""
296
+ return self._request("GET", f"/prompts/{prompt_id}")
297
+
298
+ # -- Integrations --
299
+
300
+ def get_integrations(self) -> Dict[str, Any]:
301
+ """Get current integration settings."""
302
+ return self._request("GET", "/integrations")
303
+
304
+ def update_integration(self, name: str, config: Dict[str, Any]) -> Dict[str, Any]:
305
+ """Update an integration's config."""
306
+ return self._request("PUT", f"/integrations/{name}", json=config)
307
+
308
+ def test_integration(self, name: str) -> Dict[str, Any]:
309
+ """Test an integration connection."""
310
+ return self._request("POST", f"/integrations/{name}/test")