gcae 0.8.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. gcae-0.8.0/.github/workflows/ci.yml +121 -0
  2. gcae-0.8.0/.gitignore +51 -0
  3. gcae-0.8.0/.pi/tasks/tasks-01a09bf2-e36a-73f3-815c-087dabaf5566.json +16 -0
  4. gcae-0.8.0/AGENTS.md +138 -0
  5. gcae-0.8.0/CHANGELOG.md +749 -0
  6. gcae-0.8.0/LICENSE +21 -0
  7. gcae-0.8.0/PKG-INFO +355 -0
  8. gcae-0.8.0/README.md +326 -0
  9. gcae-0.8.0/assets/readme/hero.svg +73 -0
  10. gcae-0.8.0/assets/readme/loop.svg +85 -0
  11. gcae-0.8.0/config.example.toml +106 -0
  12. gcae-0.8.0/docs/ARCHITECTURE.md +307 -0
  13. gcae-0.8.0/docs/CLI.md +155 -0
  14. gcae-0.8.0/docs/CONFIGURATION.md +132 -0
  15. gcae-0.8.0/docs/CONTEXT_RECONSTRUCTION.md +39 -0
  16. gcae-0.8.0/docs/EVIDENCE_LEDGER.md +35 -0
  17. gcae-0.8.0/docs/EXECUTION_KNOWLEDGE_SPLIT.md +19 -0
  18. gcae-0.8.0/docs/FAILURE_RECOVERY.md +70 -0
  19. gcae-0.8.0/docs/GIT_EXECUTION.md +93 -0
  20. gcae-0.8.0/docs/IMPLEMENTATION_AUDIT.md +103 -0
  21. gcae-0.8.0/docs/INTERACTIVE_EXECUTION.md +20 -0
  22. gcae-0.8.0/docs/MEMORY_CONTEXT.md +56 -0
  23. gcae-0.8.0/docs/PLAN_HISTORY.md +61 -0
  24. gcae-0.8.0/docs/PROGRESS_MODEL.md +32 -0
  25. gcae-0.8.0/docs/PROVIDERS.md +145 -0
  26. gcae-0.8.0/docs/RUNTIME_GUARDIAN.md +52 -0
  27. gcae-0.8.0/docs/STATE_MACHINE.md +114 -0
  28. gcae-0.8.0/docs/TEST_PLAN.md +64 -0
  29. gcae-0.8.0/docs/TOOLS.md +73 -0
  30. gcae-0.8.0/docs/TRAJECTORY_MODEL.md +41 -0
  31. gcae-0.8.0/docs/TUI.md +305 -0
  32. gcae-0.8.0/docs/VERIFICATION.md +24 -0
  33. gcae-0.8.0/docs/WORKSPACE_HYGIENE.md +32 -0
  34. gcae-0.8.0/pyproject.toml +54 -0
  35. gcae-0.8.0/src/gcae/__init__.py +5 -0
  36. gcae-0.8.0/src/gcae/__main__.py +4 -0
  37. gcae-0.8.0/src/gcae/cli.py +996 -0
  38. gcae-0.8.0/src/gcae/config.py +202 -0
  39. gcae-0.8.0/src/gcae/context.py +258 -0
  40. gcae-0.8.0/src/gcae/controller.py +41 -0
  41. gcae-0.8.0/src/gcae/evaluator.py +95 -0
  42. gcae-0.8.0/src/gcae/execution.py +622 -0
  43. gcae-0.8.0/src/gcae/git.py +610 -0
  44. gcae-0.8.0/src/gcae/guardian.py +618 -0
  45. gcae-0.8.0/src/gcae/http_provider.py +531 -0
  46. gcae-0.8.0/src/gcae/memory.py +326 -0
  47. gcae-0.8.0/src/gcae/merge.py +134 -0
  48. gcae-0.8.0/src/gcae/models.py +512 -0
  49. gcae-0.8.0/src/gcae/persistence.py +44 -0
  50. gcae-0.8.0/src/gcae/planner.py +166 -0
  51. gcae-0.8.0/src/gcae/progress.py +676 -0
  52. gcae-0.8.0/src/gcae/providers.py +107 -0
  53. gcae-0.8.0/src/gcae/recovery.py +238 -0
  54. gcae-0.8.0/src/gcae/runtime.py +4019 -0
  55. gcae-0.8.0/src/gcae/safeguards.py +88 -0
  56. gcae-0.8.0/src/gcae/state_machine.py +45 -0
  57. gcae-0.8.0/src/gcae/tools.py +687 -0
  58. gcae-0.8.0/src/gcae/tui/__init__.py +5 -0
  59. gcae-0.8.0/src/gcae/tui/app.py +846 -0
  60. gcae-0.8.0/src/gcae/tui/formatters.py +647 -0
  61. gcae-0.8.0/src/gcae/tui/modals.py +159 -0
  62. gcae-0.8.0/src/gcae/tui/screens.py +542 -0
  63. gcae-0.8.0/src/gcae/tui/state.py +778 -0
  64. gcae-0.8.0/src/gcae/tui/styles.tcss +262 -0
  65. gcae-0.8.0/src/gcae/tui/widgets.py +1069 -0
  66. gcae-0.8.0/src/gcae/validation.py +124 -0
  67. gcae-0.8.0/src/gcae/verifier.py +348 -0
  68. gcae-0.8.0/tests/test_adaptive_execution.py +796 -0
  69. gcae-0.8.0/tests/test_adaptive_trajectory.py +277 -0
  70. gcae-0.8.0/tests/test_cli_commands.py +559 -0
  71. gcae-0.8.0/tests/test_context_budget.py +132 -0
  72. gcae-0.8.0/tests/test_control.py +645 -0
  73. gcae-0.8.0/tests/test_guardian.py +439 -0
  74. gcae-0.8.0/tests/test_hardening.py +721 -0
  75. gcae-0.8.0/tests/test_integration_rollback.py +99 -0
  76. gcae-0.8.0/tests/test_liveness.py +1354 -0
  77. gcae-0.8.0/tests/test_phase1.py +48 -0
  78. gcae-0.8.0/tests/test_phase2.py +294 -0
  79. gcae-0.8.0/tests/test_phase3.py +93 -0
  80. gcae-0.8.0/tests/test_phase4.py +306 -0
  81. gcae-0.8.0/tests/test_phase5.py +236 -0
  82. gcae-0.8.0/tests/test_phase6.py +23 -0
  83. gcae-0.8.0/tests/test_phase7.py +668 -0
  84. gcae-0.8.0/tests/test_phase8.py +938 -0
  85. gcae-0.8.0/tests/test_plan_history.py +376 -0
  86. gcae-0.8.0/tests/test_progress.py +193 -0
  87. gcae-0.8.0/tests/test_resume_recovery.py +553 -0
  88. gcae-0.8.0/tests/test_routing.py +384 -0
  89. gcae-0.8.0/tests/test_scaffold.py +13 -0
  90. gcae-0.8.0/tests/test_semantic_steps.py +242 -0
  91. gcae-0.8.0/tests/test_tui.py +2581 -0
  92. gcae-0.8.0/tests/test_verifier.py +243 -0
  93. gcae-0.8.0/tools/publish_wiki.sh +54 -0
  94. gcae-0.8.0/tools/tui_demo.py +729 -0
  95. gcae-0.8.0/wiki/Architecture.md +88 -0
  96. gcae-0.8.0/wiki/CLI-Reference.md +128 -0
  97. gcae-0.8.0/wiki/Concepts.md +121 -0
  98. gcae-0.8.0/wiki/Configuration.md +109 -0
  99. gcae-0.8.0/wiki/Dashboard.md +79 -0
  100. gcae-0.8.0/wiki/FAQ.md +57 -0
  101. gcae-0.8.0/wiki/Git-Model.md +75 -0
  102. gcae-0.8.0/wiki/Home.md +54 -0
  103. gcae-0.8.0/wiki/Installation.md +61 -0
  104. gcae-0.8.0/wiki/Memory-and-Context.md +66 -0
  105. gcae-0.8.0/wiki/Providers.md +100 -0
  106. gcae-0.8.0/wiki/Quickstart.md +82 -0
  107. gcae-0.8.0/wiki/Troubleshooting.md +77 -0
  108. gcae-0.8.0/wiki/_Sidebar.md +29 -0
@@ -0,0 +1,121 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ tags: ["v*"]
7
+ pull_request:
8
+ branches: [main]
9
+ workflow_dispatch:
10
+
11
+ permissions:
12
+ contents: read
13
+
14
+ concurrency:
15
+ group: ${{ github.workflow }}-${{ github.ref }}
16
+ cancel-in-progress: true
17
+
18
+ env:
19
+ PIP_DISABLE_PIP_VERSION_CHECK: "1"
20
+ PYTHONUNBUFFERED: "1"
21
+
22
+ jobs:
23
+ lint:
24
+ name: lint (ruff + mypy)
25
+ runs-on: ubuntu-latest
26
+ steps:
27
+ - uses: actions/checkout@v7
28
+ - uses: actions/setup-python@v7
29
+ with:
30
+ python-version: "3.13"
31
+ cache: pip
32
+ - name: Install
33
+ run: python -m pip install -e ".[dev]"
34
+ - name: ruff
35
+ run: ruff check .
36
+ - name: mypy (strict)
37
+ run: mypy src/gcae
38
+
39
+ test:
40
+ name: test (python ${{ matrix.python-version }})
41
+ runs-on: ubuntu-latest
42
+ strategy:
43
+ fail-fast: false
44
+ matrix:
45
+ python-version: ["3.12", "3.13"]
46
+ steps:
47
+ - uses: actions/checkout@v7
48
+ - uses: actions/setup-python@v7
49
+ with:
50
+ python-version: ${{ matrix.python-version }}
51
+ cache: pip
52
+ - name: Install
53
+ run: python -m pip install -e ".[dev]"
54
+ - name: Configure git for the suites that create repositories
55
+ run: |
56
+ git config --global user.name "GCAE CI"
57
+ git config --global user.email "ci@gcae.invalid"
58
+ git config --global init.defaultBranch main
59
+ - name: pytest
60
+ run: pytest -q
61
+
62
+ build:
63
+ name: build (sdist + wheel)
64
+ runs-on: ubuntu-latest
65
+ needs: [lint, test]
66
+ steps:
67
+ - uses: actions/checkout@v7
68
+ - uses: actions/setup-python@v7
69
+ with:
70
+ python-version: "3.13"
71
+ cache: pip
72
+ - name: Install build tooling
73
+ run: python -m pip install build
74
+ - name: Build sdist and wheel
75
+ run: python -m build
76
+ - name: The wheel must install and expose the CLI
77
+ run: |
78
+ python -m venv /tmp/wheel-check
79
+ /tmp/wheel-check/bin/python -m pip install dist/*.whl
80
+ /tmp/wheel-check/bin/gcae --version
81
+ - uses: actions/upload-artifact@v7
82
+ with:
83
+ name: gcae-dist
84
+ path: dist/*
85
+ if-no-files-found: error
86
+
87
+ release:
88
+ name: release ${{ github.ref_name }}
89
+ if: startsWith(github.ref, 'refs/tags/v')
90
+ needs: [build]
91
+ runs-on: ubuntu-latest
92
+ permissions:
93
+ contents: write
94
+ steps:
95
+ - uses: actions/checkout@v7
96
+ - uses: actions/download-artifact@v8
97
+ with:
98
+ name: gcae-dist
99
+ path: dist
100
+ - name: Publish the GitHub release with the build artifacts
101
+ env:
102
+ GH_TOKEN: ${{ github.token }}
103
+ run: |
104
+ gh release create "$GITHUB_REF_NAME" dist/* \
105
+ --title "GCAE $GITHUB_REF_NAME" \
106
+ --notes-file CHANGELOG.md
107
+
108
+ publish:
109
+ name: publish to PyPI
110
+ if: startsWith(github.ref, 'refs/tags/v')
111
+ needs: [build]
112
+ runs-on: ubuntu-latest
113
+ permissions:
114
+ id-token: write # trusted publishing: no PyPI token in the repository
115
+ environment: pypi
116
+ steps:
117
+ - uses: actions/download-artifact@v8
118
+ with:
119
+ name: gcae-dist
120
+ path: dist
121
+ - uses: pypa/gh-action-pypi-publish@release/v1
gcae-0.8.0/.gitignore ADDED
@@ -0,0 +1,51 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.pyo
5
+ *.pyd
6
+ .venv/
7
+ venv/
8
+ env/
9
+ .eggs/
10
+ *.egg-info/
11
+ build/
12
+ dist/
13
+ .installed.cfg
14
+
15
+ # Tool caches
16
+ .pytest_cache/
17
+ .mypy_cache/
18
+ .ruff_cache/
19
+ .coverage
20
+ .coverage.*
21
+ htmlcov/
22
+ coverage.xml
23
+ .tox/
24
+ .nox/
25
+
26
+ # Secrets and machine-local configuration
27
+ config.toml
28
+ .env
29
+ .env.*
30
+ *.pem
31
+ *.key
32
+
33
+ # GCAE runtime data (keep it outside repositories; ignored in case one lands here)
34
+ memory.db
35
+ *.sqlite3
36
+ result.json
37
+
38
+ # Editors and operating systems
39
+ .idea/
40
+ .vscode/
41
+ *.swp
42
+ *.swo
43
+ *~
44
+ .DS_Store
45
+ Thumbs.db
46
+ desktop.ini
47
+
48
+ # Local scratch
49
+ *.log
50
+ tmp/
51
+ scratch/
@@ -0,0 +1,16 @@
1
+ {
2
+ "nextId": 6,
3
+ "tasks": [
4
+ {
5
+ "id": "5",
6
+ "subject": "Commit and push the 0.7.0 release",
7
+ "description": "Stage tracked changes only (git add -u, never the key-bearing config.openrouter.toml), commit 0.7.0, push to origin",
8
+ "status": "in_progress",
9
+ "metadata": {},
10
+ "blocks": [],
11
+ "blockedBy": [],
12
+ "createdAt": 1789553247340,
13
+ "updatedAt": 1789553250660
14
+ }
15
+ ]
16
+ }
gcae-0.8.0/AGENTS.md ADDED
@@ -0,0 +1,138 @@
1
+ # AGENTS.md — working on GCAE
2
+
3
+ Operational instructions for coding agents working **on this repository**. Detailed design lives in
4
+ `docs/`; this file states what must stay true.
5
+
6
+ ## What this project is
7
+
8
+ GCAE is **not another generic coding agent**. It is a lightweight, single-agent,
9
+ **evidence-driven execution runtime**: actions are speculative, progress must be verified,
10
+ failed execution trajectories are reversible, and the knowledge gained from both success and
11
+ failure persists across replanning. One process drives a model through semantic trajectory
12
+ steps in an isolated Git worktree, validates results deterministically, evaluates them,
13
+ checkpoints accepted work, rolls back rejected work, and keeps knowledge in SQLite across
14
+ rollbacks and runs. It runs headless or with an interactive Textual TUI that is a live
15
+ trajectory inspector, not a chat client.
16
+
17
+ The loop is:
18
+
19
+ ```
20
+ RECONSTRUCT → ACT → OBSERVE → JUDGE → COMMIT OR REVERT → LEARN → (reconstruct)
21
+ ```
22
+
23
+ ## Architectural invariants (do not break)
24
+
25
+ 1. **Execution state is reversible, knowledge is cumulative.** Git checkpoints are the trusted
26
+ state; memory (`memory.db`) survives every rollback. Rejection resets the worktree to the
27
+ accepted commit; the failure lesson and its evidence records stay. Deleting failure lessons
28
+ on rollback is a bug. Tested: `tests/test_hardening.py` (invariants A–J).
29
+ 2. **Exactly one worktree per run**, under the runtime directory. Never one worktree per step.
30
+ Never modify the user's working tree. A repository that is unborn or dirty is repaired
31
+ before the run (`auto_bootstrap`, bounded to 2000 files / 50 MB, `.gitignore` respected,
32
+ reported as a notice); a mid-merge/rebase repository and a non-repository directory are
33
+ refused.
34
+ 3. **The loop owns every git operation.** Conflicts included: a conflicting merge is brought
35
+ into the run's own worktree, resolved by the agent as a normal semantic step, re-verified
36
+ and retried; markers are never committed. Bootstrap, branches, worktrees, checkpoints,
37
+ merges and cleanup are performed by the runtime without asking the user to run git.
38
+ 4. **Every failure is diagnosed before it can end a run.** Self-recovery is the default
39
+ response: stagnation, unusable provider/evaluator output, stalls, exhausted budgets,
40
+ planner outages, unexpected exceptions and transient network errors all reach the advisor
41
+ (bounded retries and backoff first, degraded mode for bookkeeping failures). Only an
42
+ already-asked run, an advisor decision to stop, or an unusable diagnosis fails a run. See
43
+ docs/FAILURE_RECOVERY.md for the full taxonomy and ladder.
44
+ 5. **A blocked run asks after diagnosing.** Stagnation, unusable provider output and an
45
+ exhausted step budget first trigger `recovery.py`: the advisor reads the run's own trace
46
+ and returns a structured `Diagnosis`. `replan` queues the correction and grants bounded
47
+ extra iterations; otherwise the run pauses (`waiting_for_user`) or blocks (`blocked`) with
48
+ a question, keeping the plan and every accepted commit. A blocked or asked run **stays
49
+ held across restarts**: a plain resume never restarts autonomous work; an instruction or
50
+ `resume --force` (recorded) proceeds. A run only fails when the user was
51
+ asked or recovery was exhausted.
52
+ 6. **Verified work reaches the user.** A completed run merges its branch into the source
53
+ branch (`[runtime] auto_merge`, default on) with the pre-merge and merge commits recorded
54
+ in `state.json`; `gcae undo` reverses it. A run that cannot be merged reports why and
55
+ leaves the branch intact for `gcae merge`.
56
+ 7. **Only acceptance creates commits.** An accepted step commits `gcae: <goal>`; a passing
57
+ final verification with a dirty worktree commits `gcae: verified final state`; rejection
58
+ does `reset --hard accepted_commit` plus cleanup inside the worktree only. A checkpoint
59
+ means *verified enough to trust*; an uncommitted candidate is *speculative* — the TUI and
60
+ the docs use exactly those words.
61
+ 8. **The model never runs Git checkpoint commands.** Checkpoint management is runtime-owned
62
+ and `git reset|clean|commit|worktree|...` stays blocked in the command tool.
63
+ 9. **The unit of progress is a semantic trajectory step**, not a tool call. Tools run freely
64
+ inside a step; deterministic validation and evaluation happen at `complete_semantic_step`
65
+ or when `max_tool_calls_per_step` is exhausted. **Action is not progress**: stagnation is
66
+ measured by accepted checkpoints, verified criteria, new failure lessons and invalidated
67
+ hypotheses — never by activity count.
68
+ 10. **Progress must be proven.** The evidence ledger (`memory.db`, `evidence` table) records
69
+ command results, validation, interactive sessions and criterion verdicts with
70
+ supports/contradicts. Completion requires PASS for every success criterion, each mapped
71
+ to ledger evidence; no evidence means INSUFFICIENT, contradiction means FAIL. The
72
+ evaluator may say *repair* (keep the candidate, fix it) instead of rollback, and *replan*
73
+ when the path is invalid — the four transitions are distinct.
74
+ 11. **The plan is trajectory state, not disposable text.** Verified completed steps keep
75
+ stable IDs, checkpoint linkage and locks across replans; replans are deterministic
76
+ partial patches to the affected region (current + future by default), never full
77
+ rewrites. A completed step is reopened only as `invalidated` with a recorded reason
78
+ and ledger evidence, and dependents follow. Rollback to an older checkpoint
79
+ invalidates exactly the steps that no longer survive it. Tested:
80
+ `tests/test_plan_history.py`. See `docs/PLAN_HISTORY.md`.
81
+ 11. **Context is reconstructed per call** from persistent state — never a growing
82
+ conversation, never summarized summaries. Pinned data (request, constraints, criteria,
83
+ current goal, expectation, accepted commit, latest user instructions, last 8 failure
84
+ lessons) cannot be dropped by budgeting; the store keeps everything else retrievable.
85
+ Retrieval is scoped to the source repository.
86
+ 12. **Structured decisions only.** Controller, planner, evaluator and verifier outputs are
87
+ Pydantic models with bounded repair; invalid output fails the run — it never falls back
88
+ silently. The model's confidence claims are ignored; only observable evidence counts.
89
+ 13. **The TUI is first-class and must keep working headlessly.** The engine must not import
90
+ Textual; the TUI subscribes to runtime events and drives a thread-safe `RuntimeControl`.
91
+ It shows trusted past, speculative present and adaptive future; raw model streaming stays
92
+ in the logs.
93
+
94
+ ## Dependencies
95
+
96
+ Runtime dependencies are exactly `pydantic`, `httpx`, `textual`. Adding another requires a
97
+ concrete justification and a note in `docs/CONFIGURATION.md`. No agent frameworks
98
+ (LangGraph/LangChain/etc.), no vector databases, no embeddings, no message brokers, no
99
+ multi-agent orchestration, no plugins.
100
+
101
+ ## Layout
102
+
103
+ ```
104
+ src/gcae/ runtime, contracts, memory, context, tools, validation, evaluator,
105
+ verifier, planner, providers, config, cli, git, merge, execution
106
+ src/gcae/tui/ Textual app (isolated; engine never imports it)
107
+ tests/ architecture tests, TUI tests, trajectory tests, invariant tests
108
+ docs/ architecture and subsystem documentation
109
+ ```
110
+
111
+ ## Required commands
112
+
113
+ ```bash
114
+ .venv/bin/pytest -q # full suite must pass
115
+ .venv/bin/ruff check . # must be clean
116
+ .venv/bin/mypy src/gcae # strict, must be clean
117
+ ```
118
+
119
+ Run all three before considering any change complete. Add tests for behavior changes:
120
+ `tests/test_integration_rollback.py`, `tests/test_adaptive_trajectory.py`,
121
+ `tests/test_hardening.py` (invariants A–J and trajectory tests 3, 4, 6) and
122
+ `tests/test_plan_history.py` (stable prefix, invalidation, resume, TUI history) and
123
+ `tests/test_resume_recovery.py` (every crash window plus a real SIGKILL resume) must keep
124
+ passing, and TUI changes must keep `tests/test_tui.py` passing.
125
+
126
+ ## Hygiene rules for your own changes
127
+
128
+ - Modify existing modules; do not add parallel implementations or compatibility layers.
129
+ - No dead code, no unused imports/options, no speculative abstractions or factories.
130
+ - Keep the runtime loop readable in `runtime.py`; do not introduce workflow engines. New
131
+ behavior lands in the subsystem module that owns it (validation, evaluator, verifier,
132
+ recovery, memory, merge, tools, git); only loop control and phase sequencing belong in
133
+ `runtime.py`. When a change touches a cohesive block living there, extract it instead of
134
+ growing the file.
135
+ - Runtime data lives under `${XDG_STATE_HOME:-~/.local/state}/gcae`; never write runtime
136
+ state into target repositories or this repository.
137
+ - Do not commit `config.toml` (API keys) or run artifacts.
138
+ - Document behavior that ships; delete documentation for behavior that does not exist.