From 0143bdd082495fa1b23443775357312888fb0df8 Mon Sep 17 00:00:00 2001 From: jay Date: Sun, 2 Aug 2026 20:17:56 +0000 Subject: [PATCH] feat(community): establish contributor foundation Add 0BSD licensing, offline contributor CI, tested configuration examples, and the public task workflow. Carry the license through JVM and native release artifacts and document account-wide contribution boundaries. --- .github/workflows/ci.yml | 41 ++++ .github/workflows/release.yml | 27 ++- .oc_local/commands/codegeist-release.md | 2 + .oc_local/rules/codegeist-release.md | 3 +- .../rules/codegeist-task-specification.md | 35 +-- CONTRIBUTING.md | 114 +++++++++ LICENSE | 7 + README.md | 166 ++++++++++--- Taskfile.yml | 2 +- app/codegeist/cli/Taskfile.yml | 26 +++ app/codegeist/cli/pom.xml | 20 ++ .../app/CodegeistLicenseResourceTest.java | 21 ++ .../app/chat/LocalOllamaProviderIT.java | 3 + .../app/config/CodegeistExamplesTest.java | 85 +++++++ .../app/provider/ProviderCategory.java | 2 +- .../app/provider/ProviderTestCategory.java | 2 +- docs/developer/architecture/architecture.md | 17 +- .../developer/release/github-release-build.md | 26 ++- .../release/native-distribution-packaging.md | 12 +- ...build-release-and-binary-smoke-strategy.md | 38 +-- .../specification/native-packaging-posture.md | 10 +- .../runtime-harness-implementation.md | 8 +- .../testing-strategy-and-agent-rules.md | 39 ++-- docs/memory-bank/chat.md | 39 +++- docs/tasks/README.md | 77 ++++++ .../task.md | 220 ++++++++++++++++++ ...T010_01_add-0bsd-and-community-policies.md | 128 ++++++++++ ...define-public-planning-and-task-linkage.md | 126 ++++++++++ ...d-repository-checks-and-pull-request-ci.md | 124 ++++++++++ ...-onboarding-and-add-repository-examples.md | 124 ++++++++++ ...h-contributor-backlogs-and-protect-main.md | 152 ++++++++++++ ...h-provider-implementation-specification.md | 65 ++++++ ...d-workspace-tools-configuration-example.md | 52 +++++ ...ve-reflection-metadata-consistency-test.md | 64 +++++ docs/tests/README.md | 28 ++- docs/tests/codegeist-test-guidelines.md | 31 +-- docs/tests/provider-feature-tests.md | 76 +++--- docs/tests/smoke-tests.md | 5 +- examples/README.md | 33 +++ examples/codegeist.mcp.yml | 8 + examples/codegeist.ollama.yml | 6 + examples/codegeist.openai.yml | 5 + scripts/tests/artifact-smoke.ps1 | 28 +++ 43 files changed, 1896 insertions(+), 201 deletions(-) create mode 100644 .github/workflows/ci.yml create mode 100644 CONTRIBUTING.md create mode 100644 LICENSE create mode 100644 app/codegeist/cli/src/test/java/ai/codegeist/app/CodegeistLicenseResourceTest.java create mode 100644 app/codegeist/cli/src/test/java/ai/codegeist/app/config/CodegeistExamplesTest.java create mode 100644 docs/tasks/README.md create mode 100644 docs/tasks/T010_build-shared-github-contributor-foundation/task.md create mode 100644 docs/tasks/T010_build-shared-github-contributor-foundation/tasks/T010_01_add-0bsd-and-community-policies.md create mode 100644 docs/tasks/T010_build-shared-github-contributor-foundation/tasks/T010_02_define-public-planning-and-task-linkage.md create mode 100644 docs/tasks/T010_build-shared-github-contributor-foundation/tasks/T010_03_add-repository-checks-and-pull-request-ci.md create mode 100644 docs/tasks/T010_build-shared-github-contributor-foundation/tasks/T010_04_fix-onboarding-and-add-repository-examples.md create mode 100644 docs/tasks/T010_build-shared-github-contributor-foundation/tasks/T010_05_publish-contributor-backlogs-and-protect-main.md create mode 100644 docs/tasks/T011_refresh-provider-implementation-specification.md create mode 100644 docs/tasks/T012_add-workspace-tools-configuration-example.md create mode 100644 docs/tasks/T013_add-native-reflection-metadata-consistency-test.md create mode 100644 examples/README.md create mode 100644 examples/codegeist.mcp.yml create mode 100644 examples/codegeist.ollama.yml create mode 100644 examples/codegeist.openai.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..cfb076a --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,41 @@ +# ci.yml - fast contributor validation for Codegeist source changes. +# +# Pull requests and pushes to source `main` run the same deterministic +# `task cli:check` contract documented in CONTRIBUTING.md. This workflow uses no +# secrets, Docker, provider calls, native-image, QEMU, or release publication. +name: Codegeist CI + +on: + pull_request: + push: + branches: + - main + +permissions: + contents: read + +jobs: + check: + name: JVM check + runs-on: ubuntu-latest + steps: + - name: Checkout source + uses: actions/checkout@v7 + + - name: Set up Java + uses: actions/setup-java@v5 + with: + distribution: temurin + java-version: "25" + cache: maven + cache-dependency-path: app/codegeist/cli/pom.xml + + - name: Install Task + uses: go-task/setup-task@v2 + with: + version: 3.x + + - name: Run contributor check + env: + DOCKER_HOST: tcp://127.0.0.1:1 + run: task cli:check diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index efd17c4..b0ae618 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -142,6 +142,8 @@ jobs: set -euo pipefail mkdir -p target/dist + jar --list --file target/codegeist.jar | grep --fixed-strings --line-regexp 'META-INF/LICENSE' + unzip -p target/codegeist.jar META-INF/LICENSE | cmp - ../../../LICENSE cp -p target/codegeist.jar target/dist/codegeist-jvm.jar - name: Upload JVM jar artifact @@ -263,14 +265,14 @@ jobs: if-no-files-found: error path: app/codegeist/cli/target/dist/codegeist-${{ matrix.platform }}.${{ matrix.extension }} - stage-install-scripts: - name: Stage install scripts + stage-release-support: + name: Stage release support assets runs-on: ubuntu-latest steps: - name: Checkout source uses: actions/checkout@v7 - - name: Stage install script assets + - name: Stage release support assets shell: bash run: | set -euo pipefail @@ -295,13 +297,16 @@ jobs: fi cp -p "$source" "dist/$script" done + cp -p LICENSE dist/LICENSE - - name: Upload install script artifact + - name: Upload release support artifact uses: actions/upload-artifact@v7 with: - name: codegeist-install-scripts + name: codegeist-release-support if-no-files-found: error - path: dist/codegeist-install-* + path: | + dist/codegeist-install-* + dist/LICENSE checksums: name: Generate and verify checksums @@ -310,7 +315,7 @@ jobs: - metadata - build-jvm - build-native - - stage-install-scripts + - stage-release-support steps: - name: Download release artifacts uses: actions/download-artifact@v8 @@ -324,6 +329,7 @@ jobs: mkdir -p dist expected_assets=( + LICENSE codegeist-jvm.jar codegeist-linux-x64.tar.gz codegeist-windows-x64.zip @@ -388,6 +394,7 @@ jobs: mkdir -p release-assets expected_assets=( + LICENSE codegeist-jvm.jar codegeist-linux-x64.tar.gz codegeist-windows-x64.zip @@ -415,10 +422,10 @@ jobs: Validation completed in this workflow run before upload: - Maven test suite passed before packaging. - - JVM jar was packaged as a release asset without artifact smoke. - - Linux x64, Windows x64, and macOS x64 native archives were built, unpacked, and smoke-tested with --version, --show-config, and ask-driven file-edit plus shell-tool side effects. + - JVM jar was packaged with the canonical license at META-INF/LICENSE and staged as a release asset without runtime artifact smoke. + - Linux x64, Windows x64, and macOS x64 native archives were built, unpacked, and smoke-tested with the canonical LICENSE, --version, --show-config, and ask-driven file-edit plus shell-tool side effects. - Linux, macOS, and Windows install scripts were run against local release-shaped assets on their matching release runners, then staged as release assets for curl-based downloads. - - The SHA-256 checksum file was generated and verified before upload. + - The standalone LICENSE release asset and all executable assets are covered by the SHA-256 checksum file, which was generated and verified before upload. Install scripts are bootstrap helpers for the native archives. This release intentionally excludes package-manager publishing, signing, notarization, SBOM, and SLSA provenance. EOF diff --git a/.oc_local/commands/codegeist-release.md b/.oc_local/commands/codegeist-release.md index 1a0c042..0c84c81 100644 --- a/.oc_local/commands/codegeist-release.md +++ b/.oc_local/commands/codegeist-release.md @@ -244,6 +244,7 @@ codegeist-macos-x64.tar.gz codegeist-install-linux.sh codegeist-install-macos.sh codegeist-install-windows.ps1 +LICENSE SHA256SUMS.txt ``` @@ -299,6 +300,7 @@ latest_assets=( "$tmp_dir/codegeist-install-linux.sh" "$tmp_dir/codegeist-install-macos.sh" "$tmp_dir/codegeist-install-windows.ps1" + "$tmp_dir/LICENSE" "$tmp_dir/SHA256SUMS.txt" ) diff --git a/.oc_local/rules/codegeist-release.md b/.oc_local/rules/codegeist-release.md index a974f43..a4c88cd 100644 --- a/.oc_local/rules/codegeist-release.md +++ b/.oc_local/rules/codegeist-release.md @@ -132,6 +132,7 @@ codegeist-macos-x64.tar.gz codegeist-install-linux.sh codegeist-install-macos.sh codegeist-install-windows.ps1 +LICENSE SHA256SUMS.txt ``` @@ -139,7 +140,7 @@ Release asset filenames intentionally omit the version because the GitHub Releas URL and immutable `v*` tag carry the version. Keep `codegeist-jvm.jar` instead of `codegeist-jvm-any.jar`; the `jvm` suffix already distinguishes the portable JVM artifact from platform-native archives. -The install scripts are release assets for curl-based bootstrap installs and must +The install scripts and standalone canonical `LICENSE` are release assets and must stay covered by `SHA256SUMS.txt` together with the jar and native archives. The release workflow must also run each install script against local release-shaped assets on its matching native runner before upload; the macOS installer must be diff --git a/.oc_local/rules/codegeist-task-specification.md b/.oc_local/rules/codegeist-task-specification.md index 3221109..10b1378 100644 --- a/.oc_local/rules/codegeist-task-specification.md +++ b/.oc_local/rules/codegeist-task-specification.md @@ -1,14 +1,14 @@ # Codegeist Task Workflow Overlay -Use the shared task phase commands from `.opencode` for task workflow phases: +Use the shared `/task` workflow from `.opencode`: -- `/specify-task [context/instructions]` -- `/plan-task [context/instructions]` -- `/solve-task [context/instructions]` -- `/work-task [context/instructions]` +- `/task spec ""` +- `/task impl <task-ref> [instructions]` +- `/task cancel <task-ref>` +- `/task backlog <title>` -This overlay adds only Codegeist-specific guidance. Keep generic phase behavior in -`.opencode/rules/task-phases.md` and `.opencode/rules/task-workflow.md`. +This overlay adds only Codegeist-specific guidance. Keep generic task behavior in +`.opencode/rules/task-workflow.md`. ## Codegeist Guidance @@ -136,14 +136,14 @@ This overlay adds only Codegeist-specific guidance. Keep generic phase behavior `.codegeist/Dockerfile` instead. Keep Ollama models under `${OLLAMA_MODELS_DIR:-$HOME/.ollama/models}` and use `OLLAMA_ENTER=false task ollama-start` for non-interactive automation. -- For Codegeist implementation verification, prefer the Taskfile entrypoint from - `app/codegeist/cli`: run `task test`, and use `task test TEST=<test-selector>` - for focused test selectors. Do not document direct `mvn test` commands for new - implementation tasks. `task test` starts the shared host Ollama container with - `OLLAMA_ENTER=false` and ensures the selected model exists before Maven. For local - Ollama provider verification, run one command such as - `CODEGEIST_TEST_PROVIDER_CATEGORY=local task test TEST=<selector>` to enable the - local provider-call methods. +- For normal Codegeist implementation verification, use + `task cli:test-jvm TEST=<test-selector>` for focused tests and `task cli:check` + for the final contributor gate. Both force provider category `none` and avoid + Ollama and Docker. Do not document direct `mvn test` commands for new + implementation tasks. For intentional local Ollama verification, use the + separate provider-capable path, for example + `CODEGEIST_TEST_PROVIDER_CATEGORY=local task cli:test TEST=<selector>`; that task + starts Ollama and ensures the selected model exists before Maven. - For Codegeist test or smoke-script work, read `docs/tests/README.md` first. Smoke scripts must keep scan-friendly status lines and emit stable `Duration: <label>: <seconds>s` lines for meaningful Maven, package, @@ -339,7 +339,8 @@ This overlay adds only Codegeist-specific guidance. Keep generic phase behavior guard each non-config feature method with an explicit category: `local`, `remote_free`, or `remote_paid`. Do not let API-key presence or Maven's default test lifecycle trigger remote provider calls. -- Run provider feature tests through `task test`; `CODEGEIST_TEST_PROVIDER_CATEGORY` - is the only provider category gate and defaults to `none`. Config-only checks stay +- Run config-only provider tests through `task cli:test-jvm` and intentional live + provider tests through `task cli:test`; `CODEGEIST_TEST_PROVIDER_CATEGORY` is the + only provider category gate and defaults to `none`. Config-only checks stay unannotated; use `local` for local provider calls, and treat `remote_paid` as the explicit cost and rate-limit opt-in. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..b95cf46 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,114 @@ +# Contributing To Codegeist + +This guide provides the Java/core ownership, setup, and verification details for +`codegeist-ai/codegeist`. Account-wide contribution policy is maintained in the +[Codegeist community repository](https://github.com/codegeist-ai/.github/blob/main/CONTRIBUTING.md); +the coordinating T010 rollout remains open until those shared defaults and public +GitHub settings are published across every Codegeist repository. + +## Repository Ownership + +This repository owns the Java 25 Codegeist core runtime, CLI/TUI application, +provider and MCP integration, local tools, packaging, installers, and user-facing +releases. Core implementation belongs under `app/codegeist/cli` and starts from +this repository's source `main` branch. + +Use the other source repositories for shared workspace infrastructure: + +- [`codegeist-agent-kit`](https://github.com/codegeist-ai/codegeist-agent-kit) + owns shared OpenCode rules, commands, skills, plugins, and generated agent-kit + `release` content. +- [`codegeist-devcontainer-kit`](https://github.com/codegeist-ai/codegeist-devcontainer-kit) + owns the shared development image, initialization, Compose runtime, and + generated devcontainer `release` content. + +Do not implement shared-kit changes inside this repository's `.opencode` or +`.devcontainer` submodule checkouts. Make the source change and pull request in +the owning kit first; a later Codegeist change can update the pinned gitlink. + +## Contributor Setup + +Host prerequisites are Git, Docker, and either VS Code with Dev Containers or +the Dev Containers CLI. The normal clone initializes only the two shared +workspace submodules; the large `docs/third-party/*/source` research references +are not needed for ordinary development. + +```bash +git clone https://github.com/codegeist-ai/codegeist.git +cd codegeist +git submodule update --init .devcontainer .opencode +devcontainer up --workspace-folder . +devcontainer exec --workspace-folder . task cli:check +devcontainer exec --workspace-folder . task cli:run -- --version +``` + +VS Code users can choose `Reopen in Container` and run `task cli:check` plus +`task cli:run -- --version` from the container terminal instead. + +The devcontainer initialization creates ignored local/generated files such as +`.codegeist/.local.env`, `.devcontainer/.env`, +`.devcontainer/Dockerfile.merged.gen`, and generated Compose bridges. Put +machine-local values in `.codegeist/.local.env`; do not edit generated files. +Create `.codegeist/compose.local.yml` or `.codegeist/Dockerfile` only when an +intentional repository-specific override is needed. + +## Checks + +The canonical contributor and pull-request check is: + +```bash +task cli:check +``` + +It runs the JVM tests with provider category `none`, packages +`app/codegeist/cli/target/codegeist.jar`, and runs that artifact's real +`--version` command with a non-empty-output assertion. The jar includes the root +license at `META-INF/LICENSE`. It ignores ambient `TEST` and provider-category +values, is deterministic and noninteractive, and requires no Docker daemon, +Ollama service, model download, credentials, or provider call. + +Use stronger checks only when the change needs them: + +- `task cli:test-jvm TEST=<selector>` runs a focused deterministic JVM test. +- `CODEGEIST_TEST_PROVIDER_CATEGORY=local task cli:test TEST=<selector>` opts + into local-provider tests and the Taskfile-managed Ollama setup. +- `task cli:mcp-remote-smoke` opts into the Docker/Ollama MCP smoke. +- `task cli:native-smoke` builds and smokes the GraalVM native artifact. +- `task cli:final-smoke-suite` runs the environment-heavy Linux and Windows/QEMU + suite. + +Hosted provider, paid-capable provider, release, and publication checks require +their explicit documented opt-ins. Credentials alone never authorize a provider +call. Report every command run, relevant skips, and concrete blockers in the +pull request. + +## Issues, Tasks, And Pull Requests + +Use [GitHub Issues](https://github.com/codegeist-ai/codegeist/issues) for public +discovery, discussion, priority, assignment, and status. The +[Codegeist Roadmap](https://github.com/users/codegeist-ai/projects/1) provides the +account-wide view. Once work is accepted and sufficiently scoped, its matching +file under `docs/tasks/` is the primary implementation specification for goal, +acceptance criteria, file targets, non-goals, and verification. + +Ready issues link their canonical task file, and publicly tracked task files link +back to the full issue URL. Pull requests should link both, use a closing keyword +for the owning issue when appropriate, describe the implementation, and report +verification. See [`docs/tasks/README.md`](docs/tasks/README.md) before selecting +work; historical task records and an `open` task status do not by themselves mean +the work is ready for an external contributor. + +## Contribution Terms + +Codegeist-owned source and documentation are licensed under +[0BSD](LICENSE). By submitting a contribution, you agree that your contribution +is provided under the same `0BSD` terms. This project does not require a CLA or +DCO sign-off. Preserve third-party licenses, notices, vendored material, and +submodule ownership. + +The T010 rollout targets the shared +[Code of Conduct](https://github.com/codegeist-ai/.github/blob/main/CODE_OF_CONDUCT.md), +[Security Policy](https://github.com/codegeist-ai/.github/blob/main/SECURITY.md), +and [Support Guide](https://github.com/codegeist-ai/.github/blob/main/SUPPORT.md). +These links become the effective account policies when published. Do not report +vulnerabilities or credentials in public issues while that rollout is pending. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..9116b9e --- /dev/null +++ b/LICENSE @@ -0,0 +1,7 @@ +BSD Zero Clause License + +Copyright (C) 2026 Codegeist contributors + +Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/README.md b/README.md index 6fc41b3..e02c01f 100644 --- a/README.md +++ b/README.md @@ -20,8 +20,10 @@ Watch the Ubuntu contributor setup tutorial on YouTube: <https://youtu.be/pEnjYS ![Codegeist TUI creates and runs hello-world.sh](docs/user/assets/tui/tui-hello-world.gif) -Use GitHub for code, issues, roadmap, and durable technical decisions. Use -Discord for quick developer help, feedback, and sharing Codegeist workflows. +Use GitHub for code, [issues](https://github.com/codegeist-ai/codegeist/issues), +the [Codegeist Roadmap](https://github.com/users/codegeist-ai/projects/1), and +durable technical decisions. Use Discord for quick developer help, feedback, and +sharing Codegeist workflows. ## Vision @@ -49,8 +51,12 @@ vision: - a native VHS-recorded TUI hello-world smoke that verifies write and shell tool previews, workspace side effects, session state, and MP4/WebM evidence - a GraalVM native-image Maven profile and local native smoke check +- a deterministic `task cli:check` contributor gate that tests, packages, and + smokes the JVM jar without Docker or provider calls +- parser-checked Ollama, OpenAI, and MCP configuration examples under `examples/` - local Linux, Windows, and Docker-backed MCP remote smoke scripts under `scripts/tests/` +- GitHub Actions contributor CI for pull requests and pushes to source `main` - a GitHub Actions release workflow for branch validation, pre-tag validation, tag-triggered published releases, checksums, and Linux/Windows/macOS native plus install-script smokes @@ -59,7 +65,9 @@ vision: ## Development Environment -The checked-in devcontainer is the current development workspace. +The checked-in devcontainer is the current development workspace. Code changes +start from the source `main` branch; the `release` branches of the shared kits are +generated distribution content, not Codegeist implementation branches. Key properties: @@ -72,15 +80,25 @@ Key properties: when missing and ignored by Git - optional repository-specific Compose and image extensions under `.codegeist/`; the default contributor workspace does not require a GPU extension +- generated `.devcontainer/.env`, `.devcontainer/Dockerfile.merged.gen`, + `.devcontainer/compose.local.gen.yml`, and + `.devcontainer/compose.user.gen.yml` files that should not be edited directly ## Repository Layout - `.devcontainer/` - development container image and runtime setup from `codegeist-devcontainer-kit` +- `.opencode/` - shared OpenCode commands, rules, skills, and integrations from + `codegeist-agent-kit` +- `.oc_local/` - tracked Codegeist-specific OpenCode overlays - `app/codegeist/cli/` - Spring Boot CLI bootstrap application, Maven project files, and local `Taskfile.yml` +- `examples/` - safe parser-checked `codegeist.yml` starting points - `scripts/install/` - curl-downloadable release install scripts for Linux, macOS, and Windows - `scripts/tests/` - local Linux, Windows QEMU, native, MCP remote, and final smoke-suite scripts +- `docs/tasks/README.md` - local task status and public issue/task linkage guide - `docs/memory-bank/chat.md` - lightweight project memory for the repository +- `CONTRIBUTING.md` - repository-specific contributor setup and verification +- `LICENSE` - Zero Clause BSD (`0BSD`) terms for Codegeist-owned material - `README.md` - project overview ## Application Bootstrap @@ -95,7 +113,7 @@ task run From the repository root, the equivalent command is: ```bash -task -t app/codegeist/cli/Taskfile.yml run +task cli:run ``` To build a GraalVM native executable instead, use: @@ -107,7 +125,7 @@ task native From the repository root: ```bash -task -t app/codegeist/cli/Taskfile.yml native +task cli:native ``` What this does: @@ -129,6 +147,31 @@ Implementation notes: - `application.yaml` is only Spring Boot/Shell configuration; Codegeist runtime config is loaded from explicit `codegeist.yml` paths +## Contributor Check + +Run the canonical normal check from the repository root: + +```bash +task cli:check +``` + +This runs the JVM test suite with provider category `none`, packages +`app/codegeist/cli/target/codegeist.jar`, and invokes the built jar's real +`--version` command with a non-empty-output assertion. The jar carries the root +license at `META-INF/LICENSE`. The check is deterministic and noninteractive, +ignores ambient `TEST` and provider-category values, and does not start Ollama, +use Docker, download a model, read provider credentials, or call a provider. + +Use a focused selector without provider setup when iterating: + +```bash +task cli:test-jvm TEST=CodegeistExamplesTest +``` + +Native-image, local/hosted provider, Docker-backed MCP, QEMU, documentation +capture, and release checks are stronger opt-in gates. See +[`CONTRIBUTING.md`](CONTRIBUTING.md) for when to run them. + ## Local Smoke Tests Local smoke scripts live under `scripts/tests/`. The primary smoke logic is @@ -187,10 +230,10 @@ toolchain, artifact, installer, and troubleshooting guide. The MCP remote smoke starts a deterministic local Docker fixture, verifies the real `streamable_http` callback path directly, then starts local Ollama and verifies that `ask` can make the model invoke the remote MCP tool. It stays outside the default -`task test` path. +`task cli:check` path. -Native release downloads are planned as platform archives, not true single-file -executables. See `docs/developer/release/native-distribution-packaging.md` for the +Native releases use platform archives, not true single-file executables. See +`docs/developer/release/native-distribution-packaging.md` for the Linux `tar.gz`, Windows `zip`, sidecar-library, and no-single-executable rationale. Run the Linux install-script smoke in a fresh Linux QEMU guest from @@ -248,10 +291,12 @@ It validates release artifacts on GitHub-hosted runners: - `codegeist-install-linux.sh` - `codegeist-install-macos.sh` - `codegeist-install-windows.ps1` +- `LICENSE` - `SHA256SUMS.txt` -The native runner jobs build and smoke the platform archive, then run the matching -install script against local release-shaped assets. This includes +The native runner jobs build and smoke the platform archive, including an exact +copy of the root `LICENSE`, then run the matching install script against local +release-shaped assets. This includes `codegeist-install-macos.sh` on the GitHub-hosted macOS x64 runner. Release work may start on an unversioned work branch. When the work branch is @@ -273,19 +318,28 @@ See `docs/developer/release/github-release-build.md` for the full operator flow. ## Getting Started -1. Clone the repository with `git clone --recurse-submodules <repo-url>` so the nested `.opencode` and `.devcontainer` checkouts are available from the start. -2. Open the repository root in VS Code and choose `Reopen in Container`, or run - `devcontainer up --workspace-folder .` from the repository root. -3. Let `.devcontainer/initialize.sh` create `.codegeist/.local.env`, - `.codegeist/compose.local.yml`, and the generated compose overlay when they are - missing. -4. Verify that `java -version` and `native-image --version` work inside the workspace. -5. Run `task -t app/codegeist/cli/Taskfile.yml run` from the repo root, or `task run` inside `app/codegeist/cli/`. -6. Run `java -jar app/codegeist/cli/target/codegeist.jar --version` to verify the current command path. +Host prerequisites are Git, Docker, and either VS Code with Dev Containers or the +Dev Containers CLI. Ordinary contributors need only the two shared workspace +submodules; recursively initializing the large `docs/third-party/*/source` +research references is unnecessary. -If the repository was cloned without `--recurse-submodules`, Git does not let the -repository force that clone behavior afterward. Run -`git submodule update --init --recursive` before opening the devcontainer. +```bash +git clone https://github.com/codegeist-ai/codegeist.git +cd codegeist +git submodule update --init .devcontainer .opencode +devcontainer up --workspace-folder . +devcontainer exec --workspace-folder . task cli:check +devcontainer exec --workspace-folder . task cli:run -- --version +``` + +VS Code users can open the repository root and choose `Reopen in Container` +instead of running `devcontainer up`; from a terminal in that container, run +`task cli:check` and `task cli:run -- --version` directly. During startup, +`.devcontainer/initialize.sh` creates `.codegeist/.local.env`, local worktree and +OpenCode directories when needed, and ignored generated files under +`.devcontainer/`. It does not create an optional +`.codegeist/compose.local.yml` or `.codegeist/Dockerfile`; add either only for an +intentional local/repository override. ## Git Worktrees @@ -297,21 +351,69 @@ Recommended workflow: 2. Open the repository root directly through VS Code Dev Containers. 3. To open a managed worktree, start VS Code or the Dev Containers CLI with `BRANCH=<branch>` in the environment. The kit's `initializeCommand` creates - or reuses `.worktrees/<branch>` and mounts it as `/workspace`. -4. Keep root `.local.env` in the repository root; managed worktrees link back to - it automatically when `.devcontainer/initialize.sh` prepares them. - -The devcontainer kit generates `.devcontainer/.gen.env` and -`.devcontainer/compose.local.gen.yml` on startup. These files keep the container -hostname, user, UID, and GID aligned with the selected checkout without a -repo-local launcher script. + or reuses `.worktrees/<branch>` and mounts the selected checkout at its + host-matching absolute path inside the container. +4. Keep `.codegeist/.local.env` in the repository root; managed worktrees link + back to it automatically when `.devcontainer/initialize.sh` prepares them. + +The devcontainer kit generates `.devcontainer/.env`, +`.devcontainer/Dockerfile.merged.gen`, +`.devcontainer/compose.local.gen.yml`, and +`.devcontainer/compose.user.gen.yml` on startup. These files keep the container +hostname, user, UID, GID, workspace, image extension, and optional Compose bridge +aligned with the selected checkout without a repo-local launcher script. Each worktree uses the `.devcontainer/` files from its own Git state. If you change the devcontainer setup in the repository root and want the same setup in an existing worktree, update that worktree to the newer commit first. -If an older checkout is missing nested submodules, initialize them with -`git submodule update --init --recursive` before opening the devcontainer. +If an older checkout is missing the workspace submodules, initialize only +`.devcontainer` and `.opencode` with +`git submodule update --init .devcontainer .opencode` before opening the +devcontainer. + +## Configuration And Trust + +Safe starting points for the current direct `codegeist.yml` parser are in +[`examples/`](examples/). The examples are parser-tested without opening provider +or MCP connections and contain no usable credentials. + +Review local configuration before running provider-backed commands: + +- Codegeist evaluates `#{...}` string values in trusted local YAML with an + unrestricted Spring SpEL context. +- `--show-config` prints configured values without secret redaction. +- Local tools can read, write, edit, and run host processes. Current workspace + settings and path checks do not provide a sandbox or permission-prompt system. +- MCP stdio configuration can launch child processes, and package-runner commands + can download dependencies. + +Do not put credentials in tracked examples, issues, pull requests, logs, or +configuration output. + +## Contributing And Community + +Start with [`CONTRIBUTING.md`](CONTRIBUTING.md) for Java/core ownership, selective +workspace setup, checks, and pull-request expectations. Public work is discovered +and discussed in [Issues](https://github.com/codegeist-ai/codegeist/issues), with +cross-repository planning in the +[Codegeist Roadmap](https://github.com/users/codegeist-ai/projects/1). The +[`docs/tasks/README.md`](docs/tasks/README.md) guide explains how accepted issues +link to canonical local task specifications; historical tasks are not automatically +ready work. + +The T010 rollout targets these account-wide policy locations: +[Code of Conduct](https://github.com/codegeist-ai/.github/blob/main/CODE_OF_CONDUCT.md), +[Security Policy](https://github.com/codegeist-ai/.github/blob/main/SECURITY.md), +and [Support Guide](https://github.com/codegeist-ai/.github/blob/main/SUPPORT.md). +Repository-specific contribution details live here; the shared policies are not +duplicated locally. T010 remains open until the shared files and related GitHub +settings are published. Never report vulnerabilities through a public issue. + +Codegeist-owned source and documentation are available under the +[Zero Clause BSD License (`0BSD`)](LICENSE). Contributions are accepted under the +same terms without a CLA or DCO requirement; third-party licenses and notices keep +their original terms. ## Status diff --git a/Taskfile.yml b/Taskfile.yml index f53917a..c16a76b 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -1,7 +1,7 @@ # Taskfile.yml - root entrypoint for repo task shortcuts. # # Includes the CLI module Taskfile without flattening or aliases so commands stay -# namespaced, for example `task cli:test` from the repository root. +# namespaced, for example `task cli:check` from the repository root. version: '3' diff --git a/app/codegeist/cli/Taskfile.yml b/app/codegeist/cli/Taskfile.yml index 0705024..e7a720a 100644 --- a/app/codegeist/cli/Taskfile.yml +++ b/app/codegeist/cli/Taskfile.yml @@ -1,6 +1,32 @@ +# Taskfile.yml - module-local build, test, and smoke entrypoints for the CLI. +# +# `test-jvm` and `check` are the deterministic contributor/CI path. Provider, +# Docker, native-image, QEMU, documentation-capture, and release smokes remain +# explicit opt-in tasks below. + version: '3' tasks: + test-jvm: + desc: Run deterministic JVM tests without provider or Docker setup + cmds: + - CODEGEIST_TEST_PROVIDER_CATEGORY=none mvn --batch-mode --no-transfer-progress {{if .TEST}}-Dtest={{.TEST}} {{end}}test + + check: + desc: Test, package, and smoke the JVM application without external services + cmds: + # Keep this command independent of ambient TEST so the canonical gate always runs the full suite. + - CODEGEIST_TEST_PROVIDER_CATEGORY=none mvn --batch-mode --no-transfer-progress test + - mvn --batch-mode --no-transfer-progress -DskipTests clean package + - jar --list --file target/codegeist.jar | grep --fixed-strings --line-regexp 'META-INF/LICENSE' + - | + version_output="$(java -jar target/codegeist.jar --version)" + if [ -z "$(printf '%s' "$version_output" | tr -d '[:space:]')" ]; then + printf 'Packaged Codegeist jar --version output was empty\n' >&2 + exit 1 + fi + printf '%s\n' "$version_output" + test: env: OLLAMA_ENTER: 'false' diff --git a/app/codegeist/cli/pom.xml b/app/codegeist/cli/pom.xml index 035d762..7830f3e 100644 --- a/app/codegeist/cli/pom.xml +++ b/app/codegeist/cli/pom.xml @@ -16,6 +16,13 @@ <name>${project.artifactId}</name> <description>Bootstrap application for codegeist.ai</description> + <licenses> + <license> + <name>0BSD</name> + <url>https://spdx.org/licenses/0BSD.html</url> + </license> + </licenses> + <!-- Java 25 is the pinned baseline for the current Spring Boot 4 stack. --> <properties> <java.version>25</java.version> @@ -128,6 +135,19 @@ <build> <finalName>${project.artifactId}</finalName> + <resources> + <resource> + <directory>src/main/resources</directory> + </resource> + <resource> + <directory>${project.basedir}/../../..</directory> + <filtering>false</filtering> + <includes> + <include>LICENSE</include> + </includes> + <targetPath>META-INF</targetPath> + </resource> + </resources> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> diff --git a/app/codegeist/cli/src/test/java/ai/codegeist/app/CodegeistLicenseResourceTest.java b/app/codegeist/cli/src/test/java/ai/codegeist/app/CodegeistLicenseResourceTest.java new file mode 100644 index 0000000..df3432e --- /dev/null +++ b/app/codegeist/cli/src/test/java/ai/codegeist/app/CodegeistLicenseResourceTest.java @@ -0,0 +1,21 @@ +package ai.codegeist.app; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import org.junit.jupiter.api.Test; + +/** Verifies that Maven copies the canonical repository license into the JAR resource tree. */ +class CodegeistLicenseResourceTest { + + private static final Path ROOT_LICENSE = Path.of("..", "..", "..", "LICENSE").toAbsolutePath().normalize(); + private static final Path PACKAGED_LICENSE = Path.of("target", "classes", "META-INF", "LICENSE"); + + @Test + void packagedLicenseResourceMatchesRootLicense() throws IOException { + assertThat(PACKAGED_LICENSE).isRegularFile(); + assertThat(Files.readString(PACKAGED_LICENSE)).isEqualTo(Files.readString(ROOT_LICENSE)); + } +} diff --git a/app/codegeist/cli/src/test/java/ai/codegeist/app/chat/LocalOllamaProviderIT.java b/app/codegeist/cli/src/test/java/ai/codegeist/app/chat/LocalOllamaProviderIT.java index 4bc3014..c1ef484 100644 --- a/app/codegeist/cli/src/test/java/ai/codegeist/app/chat/LocalOllamaProviderIT.java +++ b/app/codegeist/cli/src/test/java/ai/codegeist/app/chat/LocalOllamaProviderIT.java @@ -7,6 +7,8 @@ import ai.codegeist.app.config.CodegeistConfigService; import ai.codegeist.app.config.OllamaProviderConfig; import ai.codegeist.app.config.ProviderConfig; +import ai.codegeist.app.provider.ProviderCategory; +import ai.codegeist.app.provider.ProviderTestCategory; import java.nio.file.Files; import java.nio.file.Path; import org.junit.jupiter.api.Test; @@ -15,6 +17,7 @@ import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.context.ConfigurableApplicationContext; +@ProviderCategory(ProviderTestCategory.local) class LocalOllamaProviderIT { private static final String OLLAMA_BASE_URL = "http://localhost:11434"; diff --git a/app/codegeist/cli/src/test/java/ai/codegeist/app/config/CodegeistExamplesTest.java b/app/codegeist/cli/src/test/java/ai/codegeist/app/config/CodegeistExamplesTest.java new file mode 100644 index 0000000..6426911 --- /dev/null +++ b/app/codegeist/cli/src/test/java/ai/codegeist/app/config/CodegeistExamplesTest.java @@ -0,0 +1,85 @@ +package ai.codegeist.app.config; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +/** + * Keeps tracked contributor examples on the production YAML loading and Bean + * Validation path. The test loads configuration only; it never creates provider + * clients, opens MCP transports, or invokes tools. + */ +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE) +class CodegeistExamplesTest { + + private static final String OPENAI_API_KEY_PLACEHOLDER = "not-a-real-openai-api-key"; + private static final Path EXAMPLES_DIRECTORY = Path.of("..", "..", "..", "examples") + .toAbsolutePath() + .normalize(); + + @Autowired + private CodegeistConfigService configService; + + @Test + void ollamaExampleParsesExpectedLocalProvider() { + CodegeistConfig config = loadExample("codegeist.ollama.yml"); + + assertThat(config.rootElements).singleElement().isInstanceOf(ProvidersRootElement.class); + assertThat(config.defaultProvider()).hasValueSatisfying(provider -> { + assertThat(provider).isInstanceOf(OllamaProviderConfig.class); + OllamaProviderConfig ollama = (OllamaProviderConfig) provider; + assertThat(ollama.getName()).isEqualTo("Local Ollama"); + assertThat(ollama.getBaseUrl()).isEqualTo("http://localhost:11434"); + assertThat(ollama.getModel()).isEqualTo("llama3.2:1b"); + }); + } + + @Test + void openAiExampleUsesOnlyNonUsableLiteralCredential() throws IOException { + Path example = examplePath("codegeist.openai.yml"); + CodegeistConfig config = configService.loadConfig(example.toString()); + + assertThat(config.rootElements).singleElement().isInstanceOf(ProvidersRootElement.class); + assertThat(config.defaultProvider()).hasValueSatisfying(provider -> { + assertThat(provider).isInstanceOf(OpenAiProviderConfig.class); + OpenAiProviderConfig openAi = (OpenAiProviderConfig) provider; + assertThat(openAi.getName()).isEqualTo("OpenAI"); + assertThat(openAi.getApiKey()).isEqualTo(OPENAI_API_KEY_PLACEHOLDER).doesNotStartWith("sk-"); + }); + assertThat(Files.readString(example)) + .contains("api-key: " + OPENAI_API_KEY_PLACEHOLDER) + .doesNotContain("#{", "getenv", "OPENAI_API_KEY", "sk-"); + } + + @Test + void mcpExampleParsesExpectedStdioClientWithoutOpeningIt() { + CodegeistConfig config = loadExample("codegeist.mcp.yml"); + + assertThat(config.rootElements).singleElement().isInstanceOf(McpClientsRootElement.class); + McpClientsConfig clients = config.rootElement(McpClientsRootElement.class).orElseThrow().getConfig(); + assertThat(clients.getElements()).singleElement().satisfies(client -> { + assertThat(client).isInstanceOf(StdioMcpClientConfig.class); + StdioMcpClientConfig stdio = (StdioMcpClientConfig) client; + assertThat(stdio.getId()).isEqualTo("filesystem"); + assertThat(stdio.getType()).isEqualTo(McpClientConfig.Type.stdio); + assertThat(stdio.getCommand()).isEqualTo("npx"); + assertThat(stdio.getArgs()).containsExactly("-y", "@modelcontextprotocol/server-filesystem", "."); + }); + } + + private CodegeistConfig loadExample(String fileName) { + return configService.loadConfig(examplePath(fileName).toString()); + } + + private Path examplePath(String fileName) { + Path example = EXAMPLES_DIRECTORY.resolve(fileName); + + assertThat(example).isRegularFile(); + return example; + } +} diff --git a/app/codegeist/cli/src/test/java/ai/codegeist/app/provider/ProviderCategory.java b/app/codegeist/cli/src/test/java/ai/codegeist/app/provider/ProviderCategory.java index 60dda0f..04e8e00 100644 --- a/app/codegeist/cli/src/test/java/ai/codegeist/app/provider/ProviderCategory.java +++ b/app/codegeist/cli/src/test/java/ai/codegeist/app/provider/ProviderCategory.java @@ -9,7 +9,7 @@ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD, ElementType.TYPE}) @ExtendWith(ProviderTestExtension.class) -@interface ProviderCategory { +public @interface ProviderCategory { ProviderTestCategory value(); } diff --git a/app/codegeist/cli/src/test/java/ai/codegeist/app/provider/ProviderTestCategory.java b/app/codegeist/cli/src/test/java/ai/codegeist/app/provider/ProviderTestCategory.java index 0b86125..6a46fd2 100644 --- a/app/codegeist/cli/src/test/java/ai/codegeist/app/provider/ProviderTestCategory.java +++ b/app/codegeist/cli/src/test/java/ai/codegeist/app/provider/ProviderTestCategory.java @@ -1,6 +1,6 @@ package ai.codegeist.app.provider; -enum ProviderTestCategory { +public enum ProviderTestCategory { none, local, diff --git a/docs/developer/architecture/architecture.md b/docs/developer/architecture/architecture.md index 6c5b62e..2f1fab6 100644 --- a/docs/developer/architecture/architecture.md +++ b/docs/developer/architecture/architecture.md @@ -826,11 +826,13 @@ download or VM prerequisites. The table below names tasks from `app/codegeist/cli/Taskfile.yml`; from the repository root, run the same commands with the `cli:` namespace, for example -`task cli:test` or `task cli:tui-capture-smoke`. +`task cli:check` or `task cli:tui-capture-smoke`. | Task | Command | Proves | | --- | --- | --- | -| `task test` | Runs `ollama-start` with `OLLAMA_ENTER=false`, then `mvn --batch-mode --no-transfer-progress {{if .TEST}}-Dtest={{.TEST}} {{end}}test` | Taskfile-managed Ollama startup, Maven test lifecycle, Spring context-load test, version output test, provider feature tests gated by `CODEGEIST_TEST_PROVIDER_CATEGORY`, and optional focused selector such as `task test TEST=CodegeistApplicationTests` | +| `task test-jvm` | Runs Maven tests with `CODEGEIST_TEST_PROVIDER_CATEGORY=none` and an optional `TEST` selector | Deterministic JVM coverage without Ollama, Docker, model downloads, credentials, or provider calls | +| `task check` | Forces the full provider-none Maven suite independently of ambient `TEST`, packages `target/codegeist.jar`, asserts `META-INF/LICENSE`, then invokes its real `--version` command | Canonical contributor and CI gate covering tests, licensing, JVM packaging, and non-empty artifact startup output | +| `task test` | Runs `ollama-start` with `OLLAMA_ENTER=false`, then Maven tests with an optional `TEST` selector | Explicit provider-capable path with Taskfile-managed Ollama startup and provider categories | | `task build` | `mvn --batch-mode --no-transfer-progress -DskipTests clean package` | Executable jar packaging | | `task tui` | Runs `build`, then `java -jar target/codegeist.jar tui` | Starts the packaged TUI from the latest local source build | | `task native` | `mvn --batch-mode --no-transfer-progress -DskipTests -Pnative clean native:compile` | GraalVM command-mode native posture when practical | @@ -858,18 +860,18 @@ path. It accepts three trigger shapes: The workflow resolves a non-SNAPSHOT SemVer release version, passes it to Maven as `-Drevision=<version>`, runs Maven tests before packaging, builds and stages a JVM -jar release asset without artifact smoke, then builds native archives on +jar release asset with canonical `META-INF/LICENSE` but without runtime artifact smoke, then builds native archives on GitHub-hosted Linux x64, Windows x64, and macOS x64 runners. Native artifact smoke runs `scripts/tests/artifact-smoke.ps1`, so release CI uses the same harness as -local platform wrappers for native packaging, archive unpacking, `--version`, -native `--show-config`, command-log assertions, deterministic file-edit side +local platform wrappers for native packaging, archive unpacking, exact `LICENSE` +comparison, `--version`, native `--show-config`, command-log assertions, deterministic file-edit side effects, and deterministic shell-tool side effects. The same native job then runs `scripts/tests/install-script-smoke.ps1` for the matching platform, including the macOS install script on the GitHub macOS x64 runner. The Windows native job activates the MSVC tools environment before running Maven native compilation. A separate staging job uploads Linux, macOS, and Windows install scripts as release -assets. The checksum job generates and verifies `SHA256SUMS.txt`; the release job -uploads the jar, native archives, install scripts, and checksum file to a published +assets together with the standalone `LICENSE`. The checksum job generates and verifies `SHA256SUMS.txt`; the release job +uploads the license, jar, native archives, install scripts, and checksum file to a published GitHub Release only for matching `v*` tags. Release workflow changes are promoted through `/codegeist-release --source @@ -897,6 +899,7 @@ The implemented release artifact names are: - `codegeist-install-linux.sh` - `codegeist-install-macos.sh` - `codegeist-install-windows.ps1` +- `LICENSE` - `SHA256SUMS.txt` ## Not Implemented Yet diff --git a/docs/developer/release/github-release-build.md b/docs/developer/release/github-release-build.md index 065566d..3358aa4 100644 --- a/docs/developer/release/github-release-build.md +++ b/docs/developer/release/github-release-build.md @@ -67,13 +67,14 @@ immutable `v*` tag carry the version, so filenames intentionally omit it: | Asset | Source job | Smoke command | | --- | --- | --- | -| `codegeist-jvm.jar` | Ubuntu JVM job | none; build and upload only | +| `codegeist-jvm.jar` | Ubuntu JVM job | package assertion for canonical `META-INF/LICENSE`; runtime artifact smoke remains outside release CI | | `codegeist-linux-x64.tar.gz` | Ubuntu native job | `scripts/tests/artifact-smoke.ps1 -Platform linux-x64` | | `codegeist-windows-x64.zip` | Windows native job | `scripts/tests/artifact-smoke.ps1 -Platform windows-x64` | | `codegeist-macos-x64.tar.gz` | macOS native job | `scripts/tests/artifact-smoke.ps1 -Platform macos-x64` | | `codegeist-install-linux.sh` | Install script staging job | `scripts/tests/install-script-smoke.ps1 -Platform linux-x64` in the native Linux job, plus parser and checksum coverage | | `codegeist-install-macos.sh` | Install script staging job | `scripts/tests/install-script-smoke.ps1 -Platform macos-x64` in the native macOS job, plus parser and checksum coverage | | `codegeist-install-windows.ps1` | Install script staging job | `scripts/tests/install-script-smoke.ps1 -Platform windows-x64` in the native Windows job, plus parser and checksum coverage | +| `LICENSE` | `stage-release-support` job | exact repository file included in `SHA256SUMS.txt` | | `SHA256SUMS.txt` | Checksum job | `sha256sum -c` before upload | Native archives keep the executable and required native sidecar libraries in one @@ -88,19 +89,22 @@ The implemented jobs run these gates in order: 1. Resolve and validate the release version. 2. Run the Maven test suite with `-Drevision=<version>`. -3. Build the executable JVM jar and stage it as `codegeist-jvm.jar` without smoke. +3. Build the executable JVM jar, verify its `META-INF/LICENSE` matches the root + license, and stage it as `codegeist-jvm.jar` without runtime artifact smoke. 4. Build native executables on GitHub-hosted Linux, Windows, and macOS runners. 5. Activate the MSVC tools environment on Windows before Maven native compile. -6. Package native archives with sidecar libraries, including the app-local MSVC CRT - on Windows. +6. Package native archives with `LICENSE` and sidecar libraries, including the + app-local MSVC CRT on Windows. 7. Run `scripts/tests/artifact-smoke.ps1` for each native platform; it packages, - unpacks, verifies `--version`, verifies `--show-config`, checks logs, and runs - deterministic file-edit plus shell-tool side effects. + unpacks, hash-compares `LICENSE`, verifies `--version`, verifies + `--show-config`, checks logs, and runs deterministic file-edit plus shell-tool + side effects. 8. Run `scripts/tests/install-script-smoke.ps1` on each native runner against the matching local archive, including macOS on `macos-15-intel`. -9. Stage Linux, macOS, and Windows install scripts as release assets. -10. Generate and verify `SHA256SUMS.txt` for the jar, native archives, and install - scripts. +9. Stage Linux, macOS, and Windows install scripts plus the standalone `LICENSE` + release asset. +10. Generate and verify `SHA256SUMS.txt` for the license, jar, native archives, and + install scripts. 11. Upload all assets as workflow artifacts. 12. On `v*` tag runs only, upload the same assets to a published GitHub Release. @@ -250,8 +254,8 @@ git push origin v0.1.1 ``` The tag push starts the release workflow automatically. The release job creates or -updates a published GitHub Release and uploads the jar, native archives, and -checksum file. +updates a published GitHub Release and uploads the license, jar, native archives, +install scripts, and checksum file. The same repo-local OpenCode command owns the full release sequence: diff --git a/docs/developer/release/native-distribution-packaging.md b/docs/developer/release/native-distribution-packaging.md index 8f2c6b6..5510ea5 100644 --- a/docs/developer/release/native-distribution-packaging.md +++ b/docs/developer/release/native-distribution-packaging.md @@ -9,10 +9,10 @@ Use one downloadable archive per platform and architecture: | Platform | Release artifact | Runtime layout inside artifact | | --- | --- | --- | -| Linux x64 | `codegeist-linux-x64.tar.gz` | `codegeist` plus required `.so` libraries in one directory. | -| Windows x64 | `codegeist-windows-x64.zip` | `codegeist.exe`, GraalVM sidecars, and the app-local MSVC CRT `.dll` libraries in one directory. | -| macOS x64 | `codegeist-macos-x64.tar.gz` | Native binary plus required dynamic libraries in one directory. | -| macOS arm64 | `codegeist-macos-aarch64.tar.gz` | Future native binary plus required dynamic libraries in one directory. | +| Linux x64 | `codegeist-linux-x64.tar.gz` | `codegeist`, `LICENSE`, and required `.so` libraries in one directory. | +| Windows x64 | `codegeist-windows-x64.zip` | `codegeist.exe`, `LICENSE`, GraalVM sidecars, and the app-local MSVC CRT `.dll` libraries in one directory. | +| macOS x64 | `codegeist-macos-x64.tar.gz` | Native binary, `LICENSE`, and required dynamic libraries in one directory. | +| macOS arm64 | `codegeist-macos-aarch64.tar.gz` | Future native binary, `LICENSE`, and required dynamic libraries in one directory. | The archive is the single download artifact. The extracted directory is the runtime unit. Users should run the executable from inside that extracted directory so the @@ -87,7 +87,7 @@ for the current platform, then smoke the unpacked archive. ```mermaid flowchart TD Build[Native build on target OS] - Output[Executable plus GraalVM sidecar libraries] + Output[Executable, LICENSE, and GraalVM sidecar libraries] Package{Platform package} Linux[codegeist-linux-x64.tar.gz] Windows[codegeist-windows-x64.zip] @@ -242,6 +242,7 @@ Planned Linux x64 package: codegeist-linux-x64.tar.gz └── codegeist-linux-x64/ ├── codegeist + ├── LICENSE ├── libawt.so ├── libawt_headless.so ├── libawt_xawt.so @@ -270,6 +271,7 @@ Current Windows x64 package: codegeist-windows-x64.zip └── codegeist-windows-x64\ ├── codegeist.exe + ├── LICENSE ├── awt.dll ├── java.dll ├── jvm.dll diff --git a/docs/developer/specification/build-release-and-binary-smoke-strategy.md b/docs/developer/specification/build-release-and-binary-smoke-strategy.md index e296f3a..e80d0ad 100644 --- a/docs/developer/specification/build-release-and-binary-smoke-strategy.md +++ b/docs/developer/specification/build-release-and-binary-smoke-strategy.md @@ -32,7 +32,7 @@ GitHub-hosted release workflow. | Spring AI Agent Utils | BOM and core dependency `0.7.0` | | JVM package | Spring Boot executable jar named `target/codegeist.jar`; release asset `codegeist-jvm.jar` | | Native package | GraalVM native Maven profile using `native-maven-plugin` `0.10.6` | -| Local commands | `task test`, `task build`, `task native`, `task native-smoke`, `task local-linux-smoke`, `task qemu-linux-install-smoke`, `task qemu-windows-smoke`, `task final-smoke-suite`, `task ollama-start`, `task run` | +| Local commands | Root `task cli:check` for normal verification; module tasks for provider, build, native, platform, release, and run workflows | | GitHub release workflow | `.github/workflows/release.yml` for `release/v*` iteration and candidate branch validation, `workflow_dispatch` pre-tag validation, and `v*` tag release publication | | Main promotion | Multi-commit release iteration branches are squashed into `release/v<version>-codegeist-rc-<n>` candidate branches; `main` is advanced by fast-forward only after candidate validation passes | @@ -57,6 +57,8 @@ associated with a `v*` release tag. Each release includes: - JVM jar artifact. - Platform-native archive artifacts when the platform build is available. - Curl-downloadable install script assets for Linux, macOS, and Windows. +- Standalone canonical `LICENSE` asset; the same license is embedded in the JVM jar + and copied into every native archive. - SHA-256 checksum file for every published artifact. - Validation summary that lists every platform check as `passed`, `skipped`, or `failed`. @@ -91,14 +93,15 @@ The JVM jar and native distribution archives have separate responsibilities. | Artifact | Example name | Built from | Verification posture | | --- | --- | --- | --- | -| JVM jar | `codegeist-jvm.jar` | Maven package on Ubuntu | Release asset only; not smoke-tested. | -| Linux native archive | `codegeist-linux-x64.tar.gz` | Native compile and package on Linux x64 | Release-blocking in the implemented workflow. | -| Windows native archive | `codegeist-windows-x64.zip` | Native compile and package on Windows x64 | Release-blocking in the implemented workflow. | -| macOS Intel native archive | `codegeist-macos-x64.tar.gz` | Native compile and package on macOS x64 | Release-blocking in the implemented workflow. | -| macOS Apple Silicon native archive | `codegeist-macos-aarch64.tar.gz` | Native compile and package on macOS arm64 | Compatibility target; skip only with explicit runner/toolchain reason. | +| JVM jar | `codegeist-jvm.jar` | Maven package on Ubuntu | Canonical license asserted at `META-INF/LICENSE`; runtime artifact smoke remains outside release CI. | +| Linux native archive | `codegeist-linux-x64.tar.gz` | Native compile and package on Linux x64 | Release-blocking; unpacked `LICENSE` must exactly match the repository file. | +| Windows native archive | `codegeist-windows-x64.zip` | Native compile and package on Windows x64 | Release-blocking; unpacked `LICENSE` must exactly match the repository file. | +| macOS Intel native archive | `codegeist-macos-x64.tar.gz` | Native compile and package on macOS x64 | Release-blocking; unpacked `LICENSE` must exactly match the repository file. | +| macOS Apple Silicon native archive | `codegeist-macos-aarch64.tar.gz` | Native compile and package on macOS arm64 | Compatibility target; when built, the archive must include the matching `LICENSE`. | | Linux install script | `codegeist-install-linux.sh` | Repo script staging job | Release asset with checksum coverage; release CI runs it on the Linux native runner, and local QEMU install smoke verifies the curl path before release when run. | | macOS install script | `codegeist-install-macos.sh` | Repo script staging job | Release asset with checksum coverage; release CI runs it on the macOS x64 native runner. | | Windows install script | `codegeist-install-windows.ps1` | Repo script staging job | Release asset with checksum coverage; release CI runs it on the Windows native runner, and local Windows QEMU smoke verifies it against local release-shaped assets. | +| License | `LICENSE` | Repository root through the `stage-release-support` job | Required standalone release asset included in checksum generation. | | Checksums | `SHA256SUMS.txt` | Platform-neutral checksum step | Required for every uploaded artifact. | Release asset filenames intentionally omit the version because the GitHub Release @@ -125,17 +128,18 @@ unsafe. `git --no-pager diff --check` for generated release changes when applicable, and verify that any multi-commit iteration branch was promoted through a single detailed squash-candidate commit. -2. Tests: run the normal Maven test lifecycle through `task test` from - `app/codegeist/cli`. -3. JVM package: run `task build` and stage the jar under a release name without - artifact smoke. +2. Tests: run the normal provider-free JVM test, package, and artifact smoke + lifecycle through `task cli:check` from the repository root. +3. JVM package: run `task build`, assert the jar's canonical `META-INF/LICENSE`, and + stage the jar under a release name without runtime artifact smoke. 4. Native compile: run `task native` on each supported native runner when the toolchain is available. 5. Native artifact smoke: run the same `scripts/tests/artifact-smoke.ps1` harness - for each native platform. It collects the executable and required sidecar - libraries into the platform archive, unpacks the archive into a clean temporary - directory, runs `--version` and `--show-config`, verifies logs, and delegates - deterministic ask-driven file editing plus shell execution to sub-harnesses. + for each native platform. It collects the executable, canonical `LICENSE`, and + required sidecar libraries into the platform archive, unpacks the archive into a + clean temporary directory, hash-compares the license, runs `--version` and + `--show-config`, verifies logs, and delegates deterministic ask-driven file + editing plus shell execution to sub-harnesses. 6. Native file-edit encoding smoke: verify each extracted native package through the shared artifact harness on the target runner. 7. Native package shape: leave only the release archive under @@ -143,8 +147,8 @@ unsafe. 8. Install script smoke: run `scripts/tests/install-script-smoke.ps1` on each native runner against the matching local archive and installer, including the macOS script on the GitHub-hosted macOS x64 runner. -9. Install script staging: upload Linux, macOS, and Windows install scripts as - release assets. +9. Release support staging: upload Linux, macOS, and Windows install scripts plus + the standalone `LICENSE` as release assets. 10. Artifact integrity: generate checksums and verify every checksum before upload. 11. Main promotion: after candidate branch validation, advance `main` by fast-forward only from the candidate commit. @@ -236,7 +240,7 @@ Actions release jobs. | Script | Current behavior | | --- | --- | | `scripts/tests/smoke-common.ps1` | Shared PowerShell 7 helper layer for platform smoke status files, duration output, environment overrides, command steps, and readiness checks. | -| `scripts/tests/artifact-smoke.ps1` | Shared native-only PowerShell 7 artifact harness used by release CI plus local Linux and Windows wrappers. It packages native artifacts, unpacks native archives, verifies `--version`, native `--show-config`, command logs, deterministic file-edit side effects, and deterministic shell side effects through fixture-backed `ask` runs. | +| `scripts/tests/artifact-smoke.ps1` | Shared native-only PowerShell 7 artifact harness used by release CI plus local Linux and Windows wrappers. It packages and hash-verifies the canonical `LICENSE`, unpacks native archives, verifies `--version`, native `--show-config`, command logs, deterministic file-edit side effects, and deterministic shell side effects through fixture-backed `ask` runs. | | `scripts/tests/install-script-smoke.ps1` | Shared install-script smoke harness used by release CI and the Windows QEMU smoke. It serves local release-shaped assets, runs the matching platform install script in an isolated install root, and verifies the installed command wrapper. | | `scripts/tests/local-linux-smoke.ps1` | Runs Maven tests, builds `target/codegeist.jar` as a build gate, and when `native-image` is available delegates native build and archive checks to `native-smoke.ps1` and the shared artifact harness for `target/dist/codegeist-linux-x64.tar.gz`. | | `scripts/tests/qemu-linux-install-smoke.sh` | Boots a fresh Ubuntu Linux QEMU guest, serves local release-shaped assets from the host, downloads `codegeist-install-linux.sh` with guest `curl`, installs the Linux archive, and verifies the installed command. It is opt-in and not part of `final-smoke-suite` by default. | diff --git a/docs/developer/specification/native-packaging-posture.md b/docs/developer/specification/native-packaging-posture.md index c752d98..1dfb797 100644 --- a/docs/developer/specification/native-packaging-posture.md +++ b/docs/developer/specification/native-packaging-posture.md @@ -52,7 +52,7 @@ files they changed. | Step | Command | Proves | Required when | | --- | --- | --- | --- | -| Compile and tests | `task test` from `app/codegeist/cli` | Maven test lifecycle and current Spring context load. | Java, dependency, build, or runtime wiring changes. | +| Compile, tests, and JVM smoke | `task cli:check` from the repository root | Provider-free Maven tests, executable jar packaging, and real jar `--version`. | Java, dependency, build, or runtime wiring changes. | | JVM package | `task build` from `app/codegeist/cli` | Executable Spring Boot jar is created as `target/codegeist.jar` for release upload. It is not smoke-tested. | Release candidates and build-layout changes. | | Native compile | `task native` from `app/codegeist/cli` | GraalVM native-image can compile the current dependency graph. | Native posture tasks when the toolchain is available and time budget allows. | | Native archive artifact smoke | `scripts/tests/artifact-smoke.ps1 -Platform <platform>` | The shared harness packages the native executable under `target/dist/`, unpacks the archive into a fresh temp directory, runs packaged `--version` and `--show-config`, verifies logs, and runs deterministic file-edit plus shell side effects through `ask`. | Release candidates after a successful native compile. | @@ -82,7 +82,7 @@ Command: task native Blocker: PF4J dynamic class loading requires explicit native-image configuration Evidence: shortest useful native-image error excerpt or issue link Owner: future extension readiness or packaging task -JVM status: passed with task test and task build +JVM status: passed with task cli:check ``` ## Blocker Categories @@ -120,9 +120,9 @@ keeps native work from becoming an unbounded rewrite. ```mermaid flowchart TD Change[Implementation or release task] - Tests[task test] - Jar[task build] - JarSmoke[java -jar target/codegeist.jar] + Tests[task cli:check] + Jar[packaged target/codegeist.jar] + JarSmoke[real jar --version] Native[task native] NativePackage[package target/dist archive] NativeSmoke[unpack archive and run packaged binary] diff --git a/docs/developer/specification/runtime-harness-implementation.md b/docs/developer/specification/runtime-harness-implementation.md index 2baf891..424512b 100644 --- a/docs/developer/specification/runtime-harness-implementation.md +++ b/docs/developer/specification/runtime-harness-implementation.md @@ -174,18 +174,18 @@ Rules: ## Verification -Implementation tasks should use the Taskfile from `app/codegeist/cli`: +Normal implementation verification should use the root Taskfile: ```bash -task test TEST=<test-selector> -task test +task cli:test-jvm TEST=<test-selector> +task cli:check ``` Use local provider verification only when a test intentionally hits the local Ollama provider: ```bash -CODEGEIST_TEST_PROVIDER_CATEGORY=local task test TEST=<test-selector> +CODEGEIST_TEST_PROVIDER_CATEGORY=local task cli:test TEST=<test-selector> ``` Documentation-only edits should run: diff --git a/docs/developer/specification/testing-strategy-and-agent-rules.md b/docs/developer/specification/testing-strategy-and-agent-rules.md index 445d03d..0e02333 100644 --- a/docs/developer/specification/testing-strategy-and-agent-rules.md +++ b/docs/developer/specification/testing-strategy-and-agent-rules.md @@ -17,7 +17,7 @@ The implemented application is currently small: provider config binding and validation, SpEL preprocessing, provider feature tests gated by `CODEGEIST_TEST_PROVIDER_CATEGORY`, and `LocalOllamaProviderIT` behind the explicit selector - `task test TEST=LocalOllamaProviderIT`. + `CODEGEIST_TEST_PROVIDER_CATEGORY=local task cli:test TEST=LocalOllamaProviderIT`. ## TDD Rules @@ -40,12 +40,17 @@ The implemented application is currently small: ## Provider Feature Tests -Provider feature tests run through `task test` and provider category checks may be -applied at method or class level. `CODEGEIST_TEST_PROVIDER_CATEGORY` defaults to -`none`, so ordinary broad verification skips annotated provider calls. `task test` -always starts the fixed local Ollama service first with `OLLAMA_ENTER=false`; set -`CODEGEIST_TEST_PROVIDER_CATEGORY=local` when local provider-call methods should -run. +Normal tests run through `task cli:test-jvm` with a command-local provider category +`none` that overrides the caller environment. The canonical `task cli:check` +ignores ambient `TEST`, runs the complete provider-none suite, adds JVM packaging, +asserts the JAR license entry, and requires non-empty artifact `--version` output +without starting providers or Docker. Live provider feature tests run through +`task cli:test`, whose explicit provider-capable path starts local Ollama before +Maven. Provider category checks may be applied at method or class level. + +Every test that can call a provider must be category-guarded even when its `*IT` +name excludes it from default Surefire discovery. An explicit `test-jvm` selector +must skip such a test under the forced `none` category. Provider categories: @@ -69,8 +74,9 @@ instance started through `task ollama-start`. - Do not use Testcontainers for the first Ollama workflow. - Do not pull, download, create, or delete local Ollama models in Java tests; the Taskfile owns host container startup and selected-model availability. -- Run provider checks with one command. `task test` invokes `ollama-start` before - Maven, and `CODEGEIST_TEST_PROVIDER_CATEGORY=local task test TEST=OllamaProviderTest` +- Run provider checks with one command. `task cli:test` invokes `ollama-start` + before Maven, and + `CODEGEIST_TEST_PROVIDER_CATEGORY=local task cli:test TEST=OllamaProviderTest` additionally enables local provider-call methods. - Keep deterministic model options such as temperature or seed in the runtime request or provider feature test method, not in provider config. @@ -81,17 +87,18 @@ instance started through `task ollama-start`. ## Current Commands -Examples from `app/codegeist/cli`: +Examples from the repository root: ```bash -task test TEST=CodegeistApplicationTests -task test TEST=CodegeistApplicationTests#contextLoads -task test +task cli:test-jvm TEST=CodegeistApplicationTests +task cli:test-jvm TEST=CodegeistApplicationTests#contextLoads +task cli:check ``` -Add task-specific `task test` commands in the active task file when new tests are -added. Do not document direct `mvn test` commands for new Codegeist implementation -tasks. +Add task-specific `task cli:test-jvm` commands in the active task file when new +deterministic tests are added. Reserve `task cli:test` for intentional provider +setup and do not document direct `mvn test` commands for new Codegeist +implementation tasks. ## Solve Checklist diff --git a/docs/memory-bank/chat.md b/docs/memory-bank/chat.md index 9b6866d..7faaa55 100644 --- a/docs/memory-bank/chat.md +++ b/docs/memory-bank/chat.md @@ -16,6 +16,14 @@ `release` branch of `codegeist-devcontainer-kit`. - `docs/memory-bank/chat.md` is the canonical lightweight project memory. The legacy root-level `chat.md` pointer has been removed. +- The open T010 contributor baseline adds root `0BSD`, repository-local + contribution/task guidance, selective workspace-submodule onboarding, + credential-free parser examples, `task cli:check`, and pull-request CI. T010 + remains open for account-wide rollout across the three source repositories plus + default-community infrastructure in `codegeist-ai/.github`, personal profile + content in `codegeist-ai/codegeist-ai`, Roadmap + `https://github.com/users/codegeist-ai/projects/1`, public issues, test pull + requests, metadata, and branch protection. - `.devcontainer` uses `.codegeist/.local.env` for ignored local runtime values and supports optional repository-specific Compose and image extensions under `.codegeist/`. Codegeist no longer checks in a mandatory NVIDIA extension, so @@ -251,8 +259,9 @@ configured `pwsh` wrapper, then asserts the workspace side effect and completed persisted shell `ToolSessionPart`. Local Linux, Windows, and release CI native smokes stay deterministic and use only the fixture-backed file-edit and - shell-tool paths. The JVM jar is built and uploaded as a release asset, but it is - not smoke-tested. + shell-tool paths. The JVM jar is built with the canonical license at + `META-INF/LICENSE` and uploaded as a release asset, but release CI does not run a + JVM artifact startup smoke. - `T007_03_add-mcp-and-read-write-tools` is completed. The slice includes direct `mcp:` config, `stdio` and `streamable_http` MCP callbacks, local `codegeist_read`, `codegeist_list`, `codegeist_glob`, `codegeist_grep`, and @@ -329,11 +338,17 @@ `logging.level.root=DEBUG` or `LOGGING_LEVEL_ROOT=DEBUG`. - The repository root `Taskfile.yml` includes `app/codegeist/cli/Taskfile.yml` under the `cli` namespace without aliases or flattening, so root commands use - `task cli:<name>`. The CLI Taskfile provides `test`, `build`, `run`, `tui`, + `task cli:<name>`. The CLI Taskfile provides `test-jvm`, `check`, `test`, + `build`, `run`, `tui`, `native`, `native-smoke`, `tui-capture-smoke`, `tui-hello-world-smoke`, `docs`, `local-linux-smoke`, `mcp-remote-smoke`, `qemu-windows-smoke`, `final-smoke-suite`, and `ollama-start`. `task cli:tui` builds the jar before launching the TUI so the - prompt surface is not stale. + prompt surface is not stale. `task cli:test-jvm` uses a command-local provider + category `none`; `task cli:check` also ignores ambient `TEST`, runs the complete + suite under `none`, packages `target/codegeist.jar`, asserts + `META-INF/LICENSE`, and requires non-empty real `--version` output without + Ollama or Docker. `LocalOllamaProviderIT` is class-gated as `local`, so selecting + it through `test-jvm` skips it rather than contacting Ollama. Local smoke scripts live under `scripts/tests/`. `task test` delegates to Maven and accepts a focused selector as `task test TEST=<test-selector>`; from the repo root use `task cli:test TEST=<test-selector>`. New implementation tasks should @@ -391,7 +406,7 @@ model wording. Smoke scripts now emit stable `Duration: <label>: <seconds>s` lines for Maven, package, native compile, archive smoke, platform total, SSH, and QEMU wrapper timings. The latest full - JVM suite passed with 191 tests, 0 failures, 0 errors, and 6 skips. The latest + JVM suite passed with 202 tests, 0 failures, 0 errors, and 6 skips. The latest `task mcp-remote-smoke` passed with `mcp remote smoke total: 13.058s`. The latest strict `task final-smoke-suite` passed with `linux platform smoke total: 85.696s`, `windows qemu smoke total: 233.055s`, `linux-x64 native shell ask total: @@ -418,9 +433,11 @@ `pwsh -NoProfile -File scripts/tests/local-linux-smoke.ps1 -RequireNative -ReleaseVersion 0.4.0`. - The release workflow builds and uploads `codegeist-jvm.jar` without artifact - smoke. The native matrix calls `scripts/tests/artifact-smoke.ps1`; the harness - packages Linux, Windows, and macOS native archives, unpacks each native archive - into a fresh temp directory, smoke-tests `--version`, native `--show-config`, logs, + startup smoke after asserting its `META-INF/LICENSE`. The native matrix calls + `scripts/tests/artifact-smoke.ps1`; the harness packages Linux, Windows, and + macOS native archives with the canonical `LICENSE`, unpacks each archive into a + fresh temp directory, hash-compares the license, smoke-tests `--version`, native + `--show-config`, logs, deterministic file-edit side effects, and deterministic shell-tool side effects before upload. Windows also packages and verifies the app-local MSVC CRT. The same native jobs then run @@ -428,8 +445,8 @@ scripts install from local release-shaped assets on their matching runners before upload. A separate install-script staging job syntax-checks and uploads `codegeist-install-linux.sh`, `codegeist-install-macos.sh`, and - `codegeist-install-windows.ps1` as release assets; `SHA256SUMS.txt` covers the jar, - native archives, and install scripts. + `codegeist-install-windows.ps1` plus standalone `LICENSE` as release assets; + `SHA256SUMS.txt` covers the license, jar, native archives, and install scripts. - Codegeist `v0.1.0` is published on GitHub Releases: `https://github.com/codegeist-ai/codegeist/releases/tag/v0.1.0`. Pre-tag validation run `26537663964`, tag run `26538176834`, and downloaded asset @@ -442,7 +459,7 @@ `codegeist-jvm.jar`, `codegeist-linux-x64.tar.gz`, `codegeist-windows-x64.zip`, `codegeist-macos-x64.tar.gz`, `codegeist-install-linux.sh`, - `codegeist-install-macos.sh`, `codegeist-install-windows.ps1`, and + `codegeist-install-macos.sh`, `codegeist-install-windows.ps1`, `LICENSE`, and `SHA256SUMS.txt`. The already-published `v0.1.0` release used the older versioned asset names. - Smoke orchestration logic now lives in PowerShell entrypoints under diff --git a/docs/tasks/README.md b/docs/tasks/README.md new file mode 100644 index 0000000..7c8295f --- /dev/null +++ b/docs/tasks/README.md @@ -0,0 +1,77 @@ +# Codegeist Task Guide + +Repository-local task files preserve implementation detail that does not fit in a +GitHub issue. They are working specifications and historical records, not a +standalone public backlog. + +Read [`CONTRIBUTING.md`](../../CONTRIBUTING.md) before starting implementation. +Codegeist also uses the account-wide +[Code of Conduct](https://github.com/codegeist-ai/.github/blob/main/CODE_OF_CONDUCT.md), +[Security Policy](https://github.com/codegeist-ai/.github/blob/main/SECURITY.md), +and [Support Guide](https://github.com/codegeist-ai/.github/blob/main/SUPPORT.md). +The T010 account rollout is still open, so do not assume a shared policy or GitHub +setting has been published merely because its target link is recorded here. + +## Statuses + +- `open` means the task still has unresolved scope or implementation work. It is + not automatically ready for an external contributor. +- `in progress` means implementation is actively underway. +- `solved`, `completed`, `implemented`, and `finalized` are historical completion + terms already used by this repository. They all mean the described work is not + available as new work. +- `deferred` means the work was intentionally postponed and needs a new readiness + decision before implementation. +- `cancelled` means the task is closed without implementation. +- `backlog` records an idea that has not yet become an accepted implementation + task. +- Historical plans, research, and solve notes remain useful context even when a + parent task still says `open`; inspect child statuses and current source before + assuming any work remains. + +New task files should use the smallest status vocabulary that accurately describes +their state. Rewrite stale status text when work changes state rather than treating +old task files as a list of ready issues. + +## Public Tracking + +The public workflow is: + +```text +Codegeist Roadmap -> repository Issue -> repository task file -> branch -> PR -> merge +``` + +- The [Codegeist Roadmap](https://github.com/users/codegeist-ai/projects/1) is the + cross-repository planning view. +- [Codegeist Issues](https://github.com/codegeist-ai/codegeist/issues) own public + discovery, discussion, priority, assignment, and status for this repository. +- A local task file owns accepted implementation scope, acceptance criteria, file + targets, non-goals, and verification. +- Every issue marked ready for implementation should link its canonical task path. +- Every publicly tracked task should replace `pending issue creation` with the full + GitHub issue URL. +- A pull request should link the issue and task, report verification, and close the + issue when the implementation is complete. Update the task status in the same + implementation unit when practical. + +Ideas do not need a task and issue immediately. Create both when maintainers accept +the work for implementation and need a durable contract. Do not mirror an entire +task specification into an issue body, and do not advertise historical, deferred, +or merely open task records as ready work. + +## Current Contributor Foundation Work + +- `T010_build-shared-github-contributor-foundation/` is the open account-wide + rollout. This repository contains its local contributor baseline, but shared + policy publication, personal account-profile publication, public issues, Roadmap + items, test pull requests, and branch protection remain outside the completed + local work. +- `T011_refresh-provider-implementation-specification.md` is a confirmed unmet + intermediate documentation candidate pending issue creation. +- `T012_add-workspace-tools-configuration-example.md` is a confirmed unmet, + beginner-safe example/test candidate pending issue creation. +- `T013_add-native-reflection-metadata-consistency-test.md` is a confirmed unmet + intermediate static-test candidate pending issue creation. + +None of these candidates is publicly ready until a maintainer creates and links its +issue and marks it ready in the repository and Roadmap. diff --git a/docs/tasks/T010_build-shared-github-contributor-foundation/task.md b/docs/tasks/T010_build-shared-github-contributor-foundation/task.md new file mode 100644 index 0000000..03ad513 --- /dev/null +++ b/docs/tasks/T010_build-shared-github-contributor-foundation/task.md @@ -0,0 +1,220 @@ +# T010 Build Shared GitHub Contributor Foundation + +Status: open + +Public tracking: create an item in the +[Codegeist Roadmap](https://github.com/users/codegeist-ai/projects/1) when the +public planning workflow from `T010_02` is available, then link this coordinating +task from the Project item. + +## Goal + +Make every non-archived public repository owned by the `codegeist-ai` GitHub +account legally, technically, and organizationally ready for external open source +contributors. + +GitHub Issues and one account-level Codegeist Roadmap project are the primary +public sources for work discovery, priority, discussion, and status. Each source +repository keeps its own canonical task file under `docs/tasks/` as the +authoritative implementation specification for accepted work, whether that task +uses the flat `TNNN_slug.md` form or nested `TNNN_slug/task.md` form. + +The completed foundation should let a contributor understand how the repositories +fit together, select the correct repository, find ready work, run that repository's +fast validation command, and submit a pull request with automatic feedback. + +## Repository Scope + +The current source repository inventory on 2026-08-02 is: + +- `codegeist-ai/codegeist` - Java CLI/TUI coding-agent runtime and user-facing + releases. +- `codegeist-ai/codegeist-agent-kit` - shared OpenCode rules, commands, skills, + scripts, plugins, and generated `release` branch content. +- `codegeist-ai/codegeist-devcontainer-kit` - shared devcontainer source and + generated `release` branch content. + +This task also creates two account infrastructure repositories: + +- `codegeist-ai/.github` for default community health files inherited by public + repositories that do not provide local overrides. +- `codegeist-ai/codegeist-ai` for the personal account profile rendered from its + root `README.md`. + +These account repositories provide community and discovery infrastructure. They do +not expand the set of source repositories that require implementation tasks, +normal source checks, ready issue backlogs, or protected source branches. + +The rollout must include public repositories added before T010 completes. Future +non-archived public repositories must follow the checklist established by this task. +Forks and vendored mirrors retain their upstream license and contribution posture +unless Codegeist owns original changes that require a clearly separated policy. + +## Current Baseline + +The 2026-08-02 public GitHub audit found: + +- `codegeist` has a 14 percent community profile, no detected license, one + release-only workflow, no open issues, and an unprotected `main` branch. +- `codegeist-agent-kit` has a 14 percent community profile, no detected license, no + GitHub Actions workflow, no open issues, and an unprotected `main` branch. +- `codegeist-devcontainer-kit` has a 28 percent community profile, no detected + license, no GitHub Actions workflow, no open issues, and an unprotected `main` + branch. +- No public `codegeist-ai/.github` default-community repository exists. +- No public `codegeist-ai/codegeist-ai` personal profile repository exists. +- Repository descriptions, homepages, topics, contribution entrypoints, issue + intake, and public roadmap coverage are incomplete or inconsistent. + +The source repositories already provide useful implementation foundations: + +- `codegeist` has detailed architecture, tests, a devcontainer, native releases, + and install scripts. +- `codegeist-agent-kit` exposes `task test` for its release bundle contract. +- Both shared kits use source `main` and generated `release` branches consumed as + submodules. + +## Decisions + +- Apply the contributor foundation to all current and future non-archived public + repositories under `codegeist-ai`, not only the core Java repository. +- Create a public `codegeist-ai/.github` repository for shared community policies, + issue forms, and pull-request defaults. +- Create a separate public `codegeist-ai/codegeist-ai` repository whose root + `README.md` is the personal account profile and public ecosystem map. +- Add a root `LICENSE` to every repository containing Codegeist-owned material; + do not rely on inherited community files for license detection. +- License Codegeist-owned source and documentation under the OSI-approved Zero + Clause BSD License, SPDX identifier `0BSD`. +- Accept external contributions under the same `0BSD` terms without a CLA or DCO + requirement in this task. +- Preserve all third-party licenses, notices, submodules, and vendored content. +- Use shared community defaults where the policy is genuinely account-wide and + repository-local overrides where build, test, release, security, or ownership + details differ. +- Use one account-level GitHub Project for public planning across repositories. +- Keep each ready issue's canonical repository-local task file as the primary + implementation contract. +- Require a repository-appropriate fast pull-request check in every source + repository; do not force unrelated repositories to use the same build command. +- Protect each public source repository's `main` branch after its required check is + proven. +- Treat generated `release` branches as distribution outputs, not contributor + implementation branches. +- Keep GitHub Discussions disabled initially. Use Issues for tracked work and + Discord for informal help. + +## Child Tasks + +- `tasks/T010_01_add-0bsd-and-community-policies.md` - create shared community + defaults and apply the license and required local policy details to every public + repository. +- `tasks/T010_02_define-public-planning-and-task-linkage.md` - define one + account-level Issue, Project, repository-task, and pull-request relationship. +- `tasks/T010_03_add-repository-checks-and-pull-request-ci.md` - add a fast local + check and pull-request CI to each source repository. +- `tasks/T010_04_fix-onboarding-and-add-repository-examples.md` - explain the + repository map, correct onboarding, and add repository-specific examples. +- `tasks/T010_05_publish-contributor-backlogs-and-protect-main.md` - publish work + across repositories, complete metadata, and protect each `main` branch. + +## Parent Acceptance Criteria + +- The public `codegeist-ai/.github` repository exists and provides default + contribution, conduct, security, support, issue, and pull-request files. +- The public `codegeist-ai/codegeist-ai` repository exists and its root `README.md` + renders the personal account profile and ecosystem map. +- Both account infrastructure repositories have a root canonical `0BSD` license. +- Every current non-archived public repository containing Codegeist-owned material + has a root canonical `0BSD` license. +- Every distributable source or generated release bundle carries the applicable + license without deleting third-party notices. +- Each repository either inherits the shared community files or provides a justified + repository-specific override linked from its README. +- Security and conduct policies use one confirmed private reporting channel and + explain any repository-specific trust boundary. +- One public Codegeist Roadmap project spans all source repositories and includes a + repository field plus `Backlog`, `Ready`, `In Progress`, `In Review`, and `Done`. +- Every repository that exposes ready implementation work has a local task guide and + bidirectional links between ready issues and canonical task files. +- `codegeist` provides `task cli:check` without Docker, Ollama, credentials, model + downloads, or hosted provider calls. +- `codegeist-agent-kit`, `codegeist-devcontainer-kit`, and future source + repositories expose and document their own fast normal check. +- Pull requests and pushes to `main` run repository-appropriate CI in every current + source repository. +- Each current public source repository's `main` requires its proven CI check and + rejects force pushes and branch deletion. +- Contributor-facing documentation explains repository ownership, source versus + generated release branches, cross-repository changes, and where tasks belong. +- At least two ready public issues exist in each current source repository, with at + least eight total and at least one realistic `good first issue` per source + repository. +- Repository descriptions, homepages, and topics are complete and consistent + across the three source and two account infrastructure repositories. +- All current repository community profiles reach the highest practical completion + level. +- A reusable checklist defines the contributor baseline for future public Codegeist + repositories. + +## Implementation Order + +1. Complete `T010_01` and create the shared `.github` plus personal profile + repositories before actively inviting contributions anywhere in the account. +2. Complete `T010_02` so all repositories use one public planning and local task + contract. +3. Complete `T010_03` and prove each source repository's normal check before + protecting its branch. +4. Complete `T010_04` and verify each source repository from a fresh checkout. +5. Complete `T010_05`, publish ready work across repositories, protect default + branches, and perform the final account-wide audit. + +## Non-Goals + +- Do not add new Codegeist runtime, provider, TUI, plugin, server, or agent-loop + features. +- Do not make every repository use Java, Maven, the same Taskfile target, or the + same release implementation. +- Do not implement source changes directly on generated `release` branches or in + consuming submodule checkouts. +- Do not add package-manager publishing, artifact signing, notarization, SBOM, or + provenance work. +- Do not require QEMU, native-image, container image builds, hosted providers, or + paid services for normal pull requests unless a repository's focused change truly + requires one and the task documents it. +- Do not rewrite every historical task or specification in one pass. + +## Verification + +Each child task owns focused checks in the repository it changes. Parent completion +additionally requires an account-wide audit that confirms: + +- the public `.github` defaults are inherited where expected; +- the root `README.md` in `codegeist-ai/codegeist-ai` renders the account profile; +- each repository has local `0BSD` license detection; +- issue and task links include the repository and path and work in both directions; +- each source repository's fast check passes from a fresh source checkout; +- a test pull request receives the required CI check in each source repository; +- the Codegeist Roadmap project contains work from all current source repositories; +- all current `main` branches have the intended protection without impossible + self-approval requirements; +- private vulnerability and conduct-reporting routes are usable; and +- community profiles and repository metadata are complete. + +## Planning Notes + +- The candidate private contact is `dev@codegeist.ai`; confirm that the mailbox is + monitored before publishing it. +- The `.github` repository reduces policy duplication but does not render this + personal account's profile. Profile content belongs in the root `README.md` of + `codegeist-ai/codegeist-ai`. +- Neither account repository can provide another repository's license. Both account + infrastructure repositories and every Codegeist-owned source repository need + their own root `LICENSE`. +- Shared kit changes must start on each kit's source `main`, pass that repository's + tests, build its generated `release` branch through the existing workflow, and + update consuming gitlinks separately. +- Prefer small public issues with observable acceptance criteria and explicit + repository ownership. +- Treat permission, workspace-containment, secret-redaction, release mutation, and + other security-sensitive work as maintainer-led rather than beginner work. diff --git a/docs/tasks/T010_build-shared-github-contributor-foundation/tasks/T010_01_add-0bsd-and-community-policies.md b/docs/tasks/T010_build-shared-github-contributor-foundation/tasks/T010_01_add-0bsd-and-community-policies.md new file mode 100644 index 0000000..6f5cd04 --- /dev/null +++ b/docs/tasks/T010_build-shared-github-contributor-foundation/tasks/T010_01_add-0bsd-and-community-policies.md @@ -0,0 +1,128 @@ +# T010_01 Add Shared 0BSD And Community Policies + +Parent: `T010_build-shared-github-contributor-foundation` + +Status: open + +Roadmap: https://github.com/users/codegeist-ai/projects/1 + +## Goal + +Establish one legal and community-policy baseline across every current public +Codegeist GitHub repository and provide inherited defaults for future repositories. + +## Decisions + +- Use the OSI-approved Zero Clause BSD License with SPDX identifier `0BSD` for all + Codegeist-owned source and documentation. +- Accept inbound contributions under the same license without a separate CLA or DCO + sign-off requirement. +- Preserve all third-party licenses and notices. +- Create `codegeist-ai/.github` for shared community health files. +- Create `codegeist-ai/codegeist-ai` for the personal account profile rendered + from its root `README.md`. +- Keep a root `LICENSE` in every repository containing Codegeist-owned material; + GitHub's inherited community files do not replace local license detection. +- Adapt Contributor Covenant 3.0 for all official Codegeist GitHub and Discord + community spaces. +- Use GitHub private vulnerability reporting where available and publish an email + address only after confirming that it is monitored. + +## Scope + +- Create the public `codegeist-ai/.github` and `codegeist-ai/codegeist-ai` + repositories. +- Add shared `CONTRIBUTING.md`, `CODE_OF_CONDUCT.md`, `SECURITY.md`, and `SUPPORT.md` + defaults to `codegeist-ai/.github`. +- Add the personal ecosystem map to the root `README.md` of + `codegeist-ai/codegeist-ai`; personal account profile content belongs only in + that repository. +- Add the canonical `0BSD` license to `.github`, `codegeist-ai`, `codegeist`, + `codegeist-agent-kit`, and `codegeist-devcontainer-kit`. +- Add `0BSD` to package metadata where a repository publishes package metadata, + including the Codegeist CLI Maven POM. +- Ensure generated shared-kit `release` branches and release bundles include the + applicable license when they distribute Codegeist-owned files. +- Link shared policies from every source README and add local policy overrides only + for real repository-specific details. +- Enable private vulnerability reporting independently in each public source + repository when GitHub supports it. +- Document the process for applying the same baseline to a future public repository. + +## Acceptance Criteria + +- `codegeist-ai/.github` is public and GitHub recognizes its default community + health files. +- `codegeist-ai/codegeist-ai` is public and GitHub renders its root `README.md` as + the personal account profile. +- Both account infrastructure repositories have root canonical `0BSD` licenses. +- Every current public Codegeist repository has a root `LICENSE` matching the + canonical OSI/SPDX `0BSD` text. +- `codegeist/app/codegeist/cli/pom.xml` declares `0BSD` with a stable license URL. +- Shared policy files contain no template placeholders and name a confirmed private + reporting route. +- Local repository policy files exist only when they add accurate repository-specific + build, test, security, or ownership guidance. +- Contributor terms state that submitted Codegeist-owned changes are accepted under + `0BSD` without a CLA or DCO requirement. +- Security guidance directs vulnerability reports away from public issues and warns + against posting credentials, tokens, or sensitive configuration output. +- Each source README links the effective contribution, conduct, security, support, + and license information. +- Generated `release` branches do not omit the license from distributed + Codegeist-owned runtime content. +- The JVM jar contains the canonical license at `META-INF/LICENSE`, every native + archive contains an exact root `LICENSE`, and the standalone release `LICENSE` + asset is covered by `SHA256SUMS.txt`. +- No third-party license, notice, vendored source, or submodule content is + relicensed. +- GitHub detects `0BSD` for every current source and account infrastructure + repository after publication. + +## Repository Targets + +- `codegeist-ai/.github` +- `codegeist-ai/codegeist-ai` +- `codegeist-ai/codegeist` +- `codegeist-ai/codegeist-agent-kit` +- `codegeist-ai/codegeist-devcontainer-kit` +- Any additional non-archived public repository created before task completion + +## Common File Targets + +- `LICENSE` +- `codegeist-ai/codegeist-ai/README.md` for the personal profile +- Source and account-infrastructure repository `README.md` files +- `CONTRIBUTING.md` when a local override is necessary +- `CODE_OF_CONDUCT.md` when a local override is necessary +- `SECURITY.md` when a local override is necessary +- `SUPPORT.md` when a local override is necessary +- Package and release manifest files that must carry license metadata +- `codegeist/.github/workflows/release.yml` and + `codegeist/scripts/tests/artifact-smoke.ps1` +- Repository-local memory or contributor documentation when present + +## Non-Goals + +- Do not add a CLA service, DCO bot, copyright assignment, dual licensing, or + commercial license. +- Do not copy identical policy files into every repository when GitHub inheritance + works and no local difference exists. +- Do not alter third-party files to make them appear covered by `0BSD`. +- Do not claim that Codegeist runtime or development environments are sandboxed. + +## Verification + +- Compare every root license with the canonical OSI/SPDX `0BSD` text. +- Parse package metadata and run each repository's focused documentation or release + manifest checks. +- Build each shared kit's test release and confirm the license is present. +- Query each GitHub community profile and license endpoint after publication. +- Verify the public personal profile renders from + `codegeist-ai/codegeist-ai/README.md`, not from the `.github` repository. +- Verify private vulnerability reporting and every public policy link manually. + +## Open Input + +Confirm whether `dev@codegeist.ai` is the monitored private address for conduct and +security reports. Do not publish an unmonitored contact. diff --git a/docs/tasks/T010_build-shared-github-contributor-foundation/tasks/T010_02_define-public-planning-and-task-linkage.md b/docs/tasks/T010_build-shared-github-contributor-foundation/tasks/T010_02_define-public-planning-and-task-linkage.md new file mode 100644 index 0000000..1657e9a --- /dev/null +++ b/docs/tasks/T010_build-shared-github-contributor-foundation/tasks/T010_02_define-public-planning-and-task-linkage.md @@ -0,0 +1,126 @@ +# T010_02 Define Account-Wide Planning And Task Linkage + +Parent: `T010_build-shared-github-contributor-foundation` + +Status: open + +Roadmap: https://github.com/users/codegeist-ai/projects/1 + +## Goal + +Define one public contribution workflow across Codegeist GitHub repositories while +keeping repository-local task files as the primary implementation specifications. + +## Workflow Contract + +```text +Account Project -> repository Issue -> canonical local task file -> branch -> PR -> merge +``` + +- The account-level Codegeist Roadmap Project owns the public cross-repository view. +- GitHub Issues own public discovery, discussion, priority, assignment, and status + inside the repository that owns the change. +- The matching repository's canonical task file under `docs/tasks/` owns + implementation scope, acceptance criteria, file targets, non-goals, and + verification. Flat `TNNN_slug.md` and nested `TNNN_slug/task.md` forms are both + supported. +- Every ready implementation issue links the repository and task path. +- Every publicly tracked task records the full issue URL or repository plus number. +- Pull requests link the issue and task and report relevant verification. +- Cross-repository work uses one coordinating Project item and explicitly linked + repository issues/tasks; it does not hide implementation work in another repo. +- Merging a pull request closes its issue and updates the local task status in the + same implementation unit when practical. + +## Scope + +- Add default bug and feature issue forms, issue configuration, and pull-request + template to `codegeist-ai/.github`. +- Add repository-specific issue or PR templates only when the shared default cannot + describe a real local requirement. +- Add or update `docs/tasks/README.md` in every repository that publishes ready + implementation work. +- Explain active, solved/finalized, deferred, cancelled, backlog, and historical task + states. +- Define a small shared label taxonomy for area, readiness, effort, security, + `good first issue`, and `help wanted`; apply labels independently in each repo. +- Create one account-level public `Codegeist Roadmap` Project with repository, + status, effort, contribution level, and area fields. +- Use Project iterations or repository-specific milestones when useful; do not treat + milestones as account-wide because GitHub milestones belong to one repository. +- Link the Roadmap, repository Issues, effective contribution guide, and local task + guide from each source README. +- Record the future-repository onboarding checklist in the shared `.github` + repository. +- Link the exact Codegeist Roadmap, the three source repositories, and the + `codegeist-ai/.github` community-policy repository from the root profile + `README.md` in `codegeist-ai/codegeist-ai`. +- Treat `.github` and `codegeist-ai` as account community/profile infrastructure; + they need implementation issues or local task guides only when work belongs to + those repositories themselves. + +## Acceptance Criteria + +- Shared issue forms and the pull-request template are inherited by repositories + without local overrides. +- Security reports are directed away from public issues. +- Each source repository documents that GitHub is public source number one for + priority/status and its canonical local task file is the primary implementation + source. +- The task guide defines when an idea needs an issue, when an issue needs a task, and + how Project, issue, task, and PR states stay synchronized. +- Existing historical task records are not presented as ready public work. +- The account-level Project can filter and group work by repository. +- A sample ready issue/task pair in each current source repository proves + bidirectional links before public backlog publication. +- A cross-repository sample proves that coordinating links do not replace local + implementation tasks. +- Shared labels have the same meaning across repositories without requiring every + repository to use irrelevant area labels. +- The personal account profile renders from `codegeist-ai/codegeist-ai/README.md` + and links the exact Roadmap plus all current source repositories. +- Both `codegeist-ai/.github` and `codegeist-ai/codegeist-ai` retain root canonical + `0BSD` licenses as account infrastructure repositories. +- Durable workflow decisions are recorded in the relevant repository memory or + contributor documentation. + +## Repository File Targets + +- `.github/ISSUE_TEMPLATE/bug.yml` +- `.github/ISSUE_TEMPLATE/feature.yml` +- `.github/ISSUE_TEMPLATE/config.yml` +- `.github/PULL_REQUEST_TEMPLATE.md` +- `codegeist-ai/.github/README.md` when a repository overview is useful +- `codegeist-ai/codegeist-ai/README.md` for the personal profile and ecosystem map +- Each source repository's `README.md` +- Each source repository's `CONTRIBUTING.md` override when needed +- Each source repository's `docs/tasks/README.md` +- Relevant repository memory files + +## GitHub Targets + +- Account-level Codegeist Roadmap Project +- `codegeist-ai/.github` default-community repository +- `codegeist-ai/codegeist-ai` personal profile repository +- Common repository labels +- Repository-specific milestones only where useful +- One sample issue/task pair per source repository +- One sample cross-repository relationship + +## Non-Goals + +- Do not mirror full task specifications into issue bodies. +- Do not store every repository's implementation tasks centrally in `codegeist`. +- Do not require task IDs to be globally unique; links must include repository and + path. +- Do not add a custom synchronization bot in the first rollout. +- Do not enable GitHub Discussions. +- Do not make Discord the source of truth for roadmap or implementation decisions. + +## Verification + +- Open the new-issue and pull-request flows in each current source repository. +- Verify shared inheritance and every justified local override. +- Inspect Project repository/status fields and sample relationships. +- Confirm all sample issue/task links in both directions. +- Run each changed repository's documentation checks and `git diff --check`. diff --git a/docs/tasks/T010_build-shared-github-contributor-foundation/tasks/T010_03_add-repository-checks-and-pull-request-ci.md b/docs/tasks/T010_build-shared-github-contributor-foundation/tasks/T010_03_add-repository-checks-and-pull-request-ci.md new file mode 100644 index 0000000..e0aa0c2 --- /dev/null +++ b/docs/tasks/T010_build-shared-github-contributor-foundation/tasks/T010_03_add-repository-checks-and-pull-request-ci.md @@ -0,0 +1,124 @@ +# T010_03 Add Repository Checks And Pull Request CI + +Parent: `T010_build-shared-github-contributor-foundation` + +Status: open + +Roadmap: https://github.com/users/codegeist-ai/projects/1 + +## Goal + +Give contributors one fast local validation command per source repository and run +the same repository-appropriate contract automatically for pull requests and normal +`main` pushes. + +## Current Problems + +- `codegeist` has only release CI. Its existing module `task test` runs + `ollama-start` before Maven even when live provider tests are skipped. +- `codegeist-agent-kit` has a focused `task test` release-bundle check but no GitHub + Actions workflow. +- `codegeist-devcontainer-kit` has no public GitHub Actions workflow and needs an + explicitly documented fast source/release validation entrypoint. +- All three current `main` branches are unprotected. +- `codegeist-ai/.github` and `codegeist-ai/codegeist-ai` are account + community/profile infrastructure, not source repositories; this task does not + invent build checks or ready implementation backlogs for them. + +## Scope + +- Audit each source repository's existing test and release entrypoints before adding + wrappers. +- Add or document one normal fast check in each source repository. +- Add `.github/workflows/ci.yml` to `codegeist`, `codegeist-agent-kit`, and + `codegeist-devcontainer-kit`. +- Configure every workflow with minimal permissions, dependency caching where + useful, no project secrets, and repository-specific failure stages. +- Run CI for pull requests and pushes to `main`. +- Keep release workflows separate from normal contributor CI. +- Validate generated release bundle contracts without publishing or pushing a + release branch. +- Document when a change needs a stronger native, container, release, or provider + check beyond the normal gate. +- Link the three source repositories and their normal checks from the account + profile in `codegeist-ai/codegeist-ai/README.md`; keep default policy ownership + discoverable from `codegeist-ai/.github/README.md` when that overview exists. + +## Codegeist Check Contract + +- Add module-local `test-jvm` and `check` tasks. +- Expose `task cli:test-jvm` and `task cli:check` from the root. +- Run provider category `none` as a command-local override without Ollama setup, + Docker, model downloads, or hosted calls. +- Ignore ambient `TEST` in the normal check so it always runs the complete suite. +- Package the JVM JAR, assert its license resource, and require non-empty output + from the real artifact's `--version` command. +- Keep explicit local/remote provider, native, QEMU, and release checks opt-in. + +## Agent Kit Check Contract + +- Use the existing `task test` release-copy smoke as the normal repository gate. +- Validate shared rule, command, skill, plugin, config, and release-path references + without building or pushing the generated `release` branch. +- Keep `task release-build` outside pull-request CI because it creates and pushes a + release commit. + +## Devcontainer Kit Check Contract + +- Define or confirm a fast repository-owned test entrypoint. +- Validate shell syntax, required release paths, generated release copy behavior, + and focused deterministic smoke checks without building the full heavyweight + devcontainer image unless the changed contract requires it. +- Keep release publication and broad image/runtime smoke separate from normal PR CI. + +## Acceptance Criteria + +- Every current source repository documents one canonical normal check. +- Each normal check is deterministic, non-interactive, and does not mutate Git + history or publish releases. +- `codegeist` normal CI makes no local or hosted model call. +- Shared-kit normal CI never pushes `release` or updates consuming gitlinks. +- CI runs for every pull request and push to `main` in all current source + repositories. +- Workflows use read-only contents permission unless one documented check requires + more. +- Failure output identifies the local stage a contributor can reproduce. +- Repository docs distinguish normal, focused, broad, release, and environment-heavy + checks. +- A test pull request proves each workflow before branch protection is enabled. +- Future repository guidance requires a normal check and pull-request CI before + advertising ready work. +- Account infrastructure repositories are explicitly excluded from source-build CI + unless they later gain repository-owned executable validation that justifies a + focused workflow. +- Both `codegeist-ai/.github` and `codegeist-ai/codegeist-ai` retain root canonical + `0BSD` licenses even though this child task does not add source-build CI to them. + +## Common File Targets + +- Each source repository's `Taskfile.yml` or existing test entrypoint +- Each source repository's `.github/workflows/ci.yml` +- Each source repository's `README.md` and `CONTRIBUTING.md` +- `codegeist-ai/codegeist-ai/README.md` for source-check discovery +- `codegeist-ai/.github/README.md` for default-community ownership when present +- Relevant test, release, architecture, and memory documentation + +## Non-Goals + +- Do not force all repositories to use the same language or exact command. +- Do not run native-image, QEMU, paid providers, hosted providers, model downloads, + full devcontainer image builds, or release pushes in normal CI. +- Do not remove stronger release validation. +- Do not add an unrelated formatter, static-analysis, coverage, or architecture + stack to every repository in this first gate. + +## Verification + +- Run each repository's normal check from a clean source checkout. +- Run `codegeist` checks with an invalid `DOCKER_HOST` to prove the normal path does + not require Docker. +- Build each shared kit's non-publishing test release and inspect its manifest. +- Parse all workflow YAML. +- Open a disposable test pull request in every current source repository and verify + the workflow reports reproducible stages. +- Run `git diff --check` in every changed repository. diff --git a/docs/tasks/T010_build-shared-github-contributor-foundation/tasks/T010_04_fix-onboarding-and-add-repository-examples.md b/docs/tasks/T010_build-shared-github-contributor-foundation/tasks/T010_04_fix-onboarding-and-add-repository-examples.md new file mode 100644 index 0000000..9cc8359 --- /dev/null +++ b/docs/tasks/T010_build-shared-github-contributor-foundation/tasks/T010_04_fix-onboarding-and-add-repository-examples.md @@ -0,0 +1,124 @@ +# T010_04 Fix Onboarding And Add Repository Examples + +Parent: `T010_build-shared-github-contributor-foundation` + +Status: open + +Roadmap: https://github.com/users/codegeist-ai/projects/1 + +## Goal + +Provide an accurate account-level repository map and a short, repository-specific +path from a fresh clone to a successful normal check and meaningful local change. + +## Shared Scope + +- Add `codegeist-ai/codegeist-ai/README.md` as the personal account profile and + public ecosystem map. +- Document `codegeist-ai/.github` separately as the default-community repository; + it owns inherited community files rather than personal profile content. +- Explain what belongs in `codegeist`, `codegeist-agent-kit`, and + `codegeist-devcontainer-kit` and where a contributor should open an issue. +- Explain source `main` versus generated `release` branches for both shared kits. +- State that implementation changes begin in the owning source repository, not in a + consuming submodule checkout or generated release branch. +- Document the cross-repository flow: source change, local tests, source PR, release + build when applicable, then a separate consuming gitlink update. +- Add a compact first-contribution path and link the account Roadmap. +- Distinguish inherited community guidance from repository-local instructions. + +## Codegeist Scope + +- Correct stale devcontainer file names, generated-file behavior, workspace paths, + and environment-file locations. +- List actual host prerequisites and make selective initialization of + `.devcontainer` plus `.opencode` the normal path. +- Keep recursive third-party source initialization research-only. +- Add safe Ollama, OpenAI, and MCP configuration examples with parser tests. +- Add a short security/trust section covering side-effecting tools, workspace policy, + trusted local expressions, and sensitive config output. +- Improve current-versus-historical documentation navigation. + +## Shared Kit Scope + +- Document each kit's source checkout, normal check, release-copy test, generated + release workflow, consumer installation/update path, and local extension boundary. +- Add small non-destructive usage examples for adding or updating each submodule. +- Make clear which files are source-only and which are shipped on `release`. +- Document how contributors verify a change without publishing a release. + +## Expected Codegeist Contributor Path + +```bash +git clone https://github.com/codegeist-ai/codegeist.git +cd codegeist +git submodule update --init .devcontainer .opencode +devcontainer up --workspace-folder . +devcontainer exec --workspace-folder . task cli:check +devcontainer exec --workspace-folder . task cli:run -- --version +``` + +## Codegeist Example Targets + +```text +examples/ +|-- README.md +|-- codegeist.ollama.yml +|-- codegeist.openai.yml +`-- codegeist.mcp.yml +``` + +## Acceptance Criteria + +- The root `README.md` in `codegeist-ai/codegeist-ai` renders the account profile + and maps both account infrastructure repositories plus every current source + repository and contributor role. +- Every source README explains purpose, source branch, normal check, contribution + guide, Issues, Roadmap, and effective license/policies. +- Shared kit docs clearly prohibit implementation work directly on generated + `release` branches and consuming submodule checkouts. +- Each source repository's documented normal check works from a fresh clone. +- Codegeist setup matches current devcontainer behavior and does not recursively + clone third-party references by default. +- Codegeist examples contain no usable credentials and parse through the production + config parser without making provider calls. +- A contributor can identify which repository owns a core runtime, OpenCode + workspace, or devcontainer change without private clarification. +- Documentation indexes route contributors to current behavior before historical + planning records. +- Future-repository guidance requires a purpose statement, ownership boundary, + normal check, Issues link, Roadmap link, license, and contribution path. +- Both `codegeist-ai/.github` and `codegeist-ai/codegeist-ai` retain root canonical + `0BSD` licenses and are identified as account infrastructure rather than source + repositories. + +## Common File Targets + +- `codegeist-ai/codegeist-ai/README.md` +- `codegeist-ai/.github/README.md` when documenting default-community ownership +- Each source repository's `README.md` +- Each source repository's `CONTRIBUTING.md` override when needed +- Each source repository's developer or release documentation +- `codegeist/examples/` +- `codegeist` example parser tests +- Relevant repository memory files + +## Non-Goals + +- Do not make every repository use the Codegeist Java devcontainer workflow. +- Do not initialize third-party research submodules by default. +- Do not make real provider calls in examples or docs verification. +- Do not promise sandboxing, permission prompts, or secret redaction that is not + implemented. +- Do not duplicate an entire shared guide locally when a short repository-specific + override and link is sufficient. + +## Verification + +- Follow each source repository's onboarding from a disposable fresh clone. +- Confirm both shared kits can test their release bundle without pushing it. +- Parse every tracked Codegeist example. +- Check every account-profile and README repository link. +- Confirm the profile renders from `codegeist-ai/codegeist-ai/README.md` and the + `.github` repository remains limited to default-community ownership. +- Run each source repository's normal check and `git diff --check`. diff --git a/docs/tasks/T010_build-shared-github-contributor-foundation/tasks/T010_05_publish-contributor-backlogs-and-protect-main.md b/docs/tasks/T010_build-shared-github-contributor-foundation/tasks/T010_05_publish-contributor-backlogs-and-protect-main.md new file mode 100644 index 0000000..a547c2d --- /dev/null +++ b/docs/tasks/T010_build-shared-github-contributor-foundation/tasks/T010_05_publish-contributor-backlogs-and-protect-main.md @@ -0,0 +1,152 @@ +# T010_05 Publish Contributor Backlogs And Protect Main + +Parent: `T010_build-shared-github-contributor-foundation` + +Status: open + +Roadmap: https://github.com/users/codegeist-ai/projects/1 + +## Goal + +Finish the account-wide contributor rollout by publishing real scoped work in every +current source repository, completing discovery metadata, and protecting each +`main` branch with its proven CI gate. + +## Scope + +- Set accurate descriptions, homepages, and topics for `.github`, `codegeist-ai`, + `codegeist`, `codegeist-agent-kit`, and `codegeist-devcontainer-kit`. +- Populate the account-level Codegeist Roadmap Project with work from every current + source repository. +- Add repository, status, area, effort, and contribution-level Project fields. +- Create at least two ready public issues in each current source repository, at + least eight meaningful issues overall across the three source repositories, and + at least one realistic `good first issue` in each source repository. +- Create or link the matching repository-local task specification for every issue + marked `Ready`. +- Use `help wanted` only for sufficiently specified intermediate work. +- Keep security, permission, secret handling, generated-release mutation, and broad + architecture decisions maintainer-led. +- Protect `main` in every current public source repository after its contributor CI + passes on a test pull request. +- Require the repository's normal CI check, reject force pushes and branch deletion, + and avoid impossible self-approval while Codegeist has one maintainer. +- Add a checklist for repeating the full baseline whenever a new public repository + is created. +- Run a final account-wide public-state and community-profile review. + +## Candidate Issue Areas + +Confirm each candidate is still unmet before publishing it. + +### Codegeist + +- Split `CodegeistLocalToolsTest` into focused per-tool test classes. +- Add native-image reflection metadata consistency coverage. +- Add architecture-boundary tests for provider, MCP, chat, and tool packages. +- Add a Maven Wrapper and enforce supported Java and Maven versions. +- Refresh stale provider implementation specifications against current architecture. +- Design maintainer-led permission and workspace-containment behavior. + +### Codegeist Agent Kit + +- Validate cross-references between commands, rules, skills, plugins, and config. +- Expand release-bundle manifest checks for required and forbidden paths. +- Add focused schema or structural validation for shared OpenCode configuration. +- Improve contributor documentation for generic versus repository-local behavior. +- Audit mutable tool/version references and propose reproducible pins where useful. + +### Codegeist Devcontainer Kit + +- Add focused shell syntax and generated-release manifest checks. +- Document image-extension, Compose-override, and consuming-repository boundaries. +- Add deterministic tests for release-copy path completeness. +- Audit mutable installer and package inputs and propose reproducibility improvements. +- Improve contributor guidance for browser, Docker, worktree, and environment setup. + +The first `good first issue` in each repository should come from documentation, +small deterministic tests, or safe structural validation. Do not label runtime +security policy, release publication, broad image builds, or provider work as +beginner work. + +## Metadata Targets + +- `.github`: shared Codegeist default community health files and contribution + intake; it does not render the personal account profile. +- `codegeist-ai`: personal account profile and ecosystem map rendered from the + repository root `README.md`. +- `codegeist`: open source Java coding agent with CLI/TUI, MCP, local models, and + native cross-platform releases; homepage `https://codegeist.ai`. +- `codegeist-agent-kit`: shared OpenCode rules, commands, skills, integrations, and + generated workspace release content. +- `codegeist-devcontainer-kit`: shared reproducible development-container source and + generated consumer release content. + +## Acceptance Criteria + +- Every current public repository has a non-empty accurate description, homepage + where applicable, and focused topics. +- The account Roadmap contains ready work from all current source repositories. +- Each current source repository has at least two ready scoped issues and one + realistic `good first issue`. +- At least eight issues are open across the three source repositories and no issue + exists only to meet the count. +- Every ready issue links a canonical local task file, and the task links back. +- Project views can group work by repository and status. +- Each current source repository's `main` requires its proven CI check and rejects + force pushes and deletion. +- Branch protection does not require self-approval from the sole maintainer. +- Generated `release` branches keep their existing controlled publication workflow + and are not used for contributor implementation. +- Every source README links its Issue list, the exact account Roadmap, effective + contribution guide, local task guide, and license. +- `codegeist-ai/codegeist-ai/README.md` renders the personal account profile and + links the source repositories, exact Roadmap, and default-community repository. +- Both `codegeist-ai/.github` and `codegeist-ai/codegeist-ai` have root canonical + `0BSD` licenses. +- Community profiles reach the highest practical score for all current repositories. +- The shared future-repository checklist is complete and linked from `.github`. +- T010 parent and child statuses plus relevant project memories match the public + final state. + +## File Targets + +- `codegeist-ai/codegeist-ai/README.md` +- `codegeist-ai/.github/README.md` when documenting default-community ownership +- Each source repository's `README.md` +- Each source repository's local task guide +- New repository-local task specifications for ready issues +- Relevant repository memory files +- `docs/tasks/T010_build-shared-github-contributor-foundation/` + +## GitHub Targets + +- Account-level Codegeist Roadmap Project and views +- Descriptions, homepages, and topics for all three source plus both account + infrastructure repositories +- Source-repository Issues and labels +- Each current source repository's `main` ruleset +- Community profiles + +## Non-Goals + +- Do not manufacture broad placeholder issues only to increase issue count. +- Do not centralize every repository's tasks in the core `codegeist` repository. +- Do not mark release, QEMU, hosted-provider, permission, secret, or security-policy + work as `good first issue`. +- Do not require pull-request approval until a second active reviewer exists. +- Do not enable GitHub Discussions. + +## Verification + +- Use GitHub UI or authenticated `gh` queries to verify metadata, issue labels, + Project membership, task links, and branch rules in every current repository. +- Open a disposable test pull request in each source repository before enabling its + required check. +- Verify that failing CI blocks merge and successful CI permits the sole-maintainer + workflow. +- Query every community profile and license endpoint. +- Verify the personal profile renders from `codegeist-ai/codegeist-ai/README.md`, + inherited defaults come from `codegeist-ai/.github`, and both have detected + `0BSD` licenses. +- Run each source repository's normal check and `git diff --check`. diff --git a/docs/tasks/T011_refresh-provider-implementation-specification.md b/docs/tasks/T011_refresh-provider-implementation-specification.md new file mode 100644 index 0000000..a5052c6 --- /dev/null +++ b/docs/tasks/T011_refresh-provider-implementation-specification.md @@ -0,0 +1,65 @@ +# T011 Refresh Provider Implementation Specification + +Status: open + +Public Tracking: pending issue creation. + +Contribution Level: intermediate (`help wanted` candidate, not `good first issue`) + +Effort: medium + +Confirmed Unmet: on 2026-08-02, +`docs/developer/specification/llm-provider-implementation.md` still models +`CodegeistConfig` as `@ConfigurationProperties`, puts provider config in the +planned `CodegeistChatRequest`, treats Ollama as the only implemented adapter, and +describes implemented tool/session behavior as future work. + +## Goal + +Refresh the provider implementation specification so it clearly separates current +Ollama/OpenAI runtime behavior from future provider guidance and no longer teaches +obsolete pre-implementation contracts. + +## Acceptance Criteria + +- The specification no longer describes `CodegeistConfig` as a Spring + `@ConfigurationProperties` provider map. +- The documented `CodegeistChatRequest` excludes provider configuration and matches + the current request/turn split. +- Current Ollama and OpenAI adapters, provider-owned default models, tool-aware + message flow, agent-loop dispatch, and session/harness ownership are described + accurately. +- Statements that only applied before OpenAI, tools, and resumable sessions were + implemented are removed or explicitly labeled historical/future. +- Provider categories and the no-provider-call default remain aligned with + `docs/tests/provider-feature-tests.md` and the canonical `task cli:check` gate. +- Diagrams render and distinguish implemented classes from illustrative future + provider classes. + +## Files + +- `docs/developer/specification/llm-provider-implementation.md` +- `docs/developer/architecture/provider-configuration.md` only if a cross-link or + current-state correction is required +- `docs/tests/provider-feature-tests.md` only if a stale shared statement is found + +## Non-Goals + +- Do not add or change Java runtime behavior, providers, models, dependencies, or + configuration fields. +- Do not make provider calls or require credentials. +- Do not redesign the provider architecture. +- Do not expand this into a general documentation rewrite; the contributor must + understand the current config, chat, agent-loop, and session boundaries, so this + is not beginner-safe work. + +## Verification + +```bash +task cli:check +git --no-pager diff --check +``` + +Review the final document against the current classes under +`app/codegeist/cli/src/main/java/ai/codegeist/app/chat` and +`app/codegeist/cli/src/main/java/ai/codegeist/app/config`. diff --git a/docs/tasks/T012_add-workspace-tools-configuration-example.md b/docs/tasks/T012_add-workspace-tools-configuration-example.md new file mode 100644 index 0000000..cf1f451 --- /dev/null +++ b/docs/tasks/T012_add-workspace-tools-configuration-example.md @@ -0,0 +1,52 @@ +# T012 Add Workspace And Local Tool Configuration Example + +Status: open + +Public Tracking: pending issue creation. + +Contribution Level: beginner (`good first issue` candidate) + +Effort: small + +Confirmed Unmet: on 2026-08-02, `examples/` has parser-checked Ollama, OpenAI, +and MCP files but no example for the implemented `workspace:` and `tools:` roots. + +## Goal + +Add one credential-free example for the implemented workspace, edit-preview, and +shell-timeout settings and keep it on the same production-parser test path as the +existing contributor examples. + +## Acceptance Criteria + +- `examples/codegeist.tools.yml` contains only implemented `workspace:` and + `tools:` fields. +- The example uses a relative workspace, keeps the directory guard enabled, and + demonstrates bounded edit-preview and positive shell-timeout settings. +- The example contains no credentials, provider, MCP process, command prefix, or + executable command. +- `examples/README.md` explains that parsing the file has no tool side effects and + that running Codegeist tools can still read, mutate, or execute on the host. +- `CodegeistExamplesTest` includes the new file and loads it through + `CodegeistConfigService` without provider, MCP, Docker, or tool calls. + +## Files + +- `examples/codegeist.tools.yml` +- `examples/README.md` +- `app/codegeist/cli/src/test/java/ai/codegeist/app/config/CodegeistExamplesTest.java` + +## Non-Goals + +- Do not change production configuration classes or tool behavior. +- Do not disable the workspace directory guard or present any setting as a + sandbox, permission system, or secret-redaction mechanism. +- Do not add a provider or MCP client to this example. + +## Verification + +```bash +task cli:test-jvm TEST=CodegeistExamplesTest +DOCKER_HOST=tcp://127.0.0.1:1 task cli:check +git --no-pager diff --check +``` diff --git a/docs/tasks/T013_add-native-reflection-metadata-consistency-test.md b/docs/tasks/T013_add-native-reflection-metadata-consistency-test.md new file mode 100644 index 0000000..cbe00aa --- /dev/null +++ b/docs/tasks/T013_add-native-reflection-metadata-consistency-test.md @@ -0,0 +1,64 @@ +# T013 Add Native Reflection Metadata Consistency Test + +Status: open + +Public Tracking: pending issue creation. + +Roadmap: https://github.com/users/codegeist-ai/projects/1 + +Contribution Level: intermediate (`help wanted` candidate, not `good first issue`) + +Effort: medium + +Confirmed Unmet: on 2026-08-02, +`app/codegeist/cli/src/main/resources/META-INF/native-image/reflect-config.json` +manually lists config models, local-tool input records, and session-store types, +but no JVM test parses that file or detects duplicate, missing, or stale class +registrations. + +## Goal + +Add deterministic JVM coverage that keeps Codegeist-owned native reflection +metadata aligned with the classes reached through Jackson config mapping, local +tool input parsing, and session-store serialization. + +## Acceptance Criteria + +- A focused JVM test parses `reflect-config.json` through a real JSON parser. +- The test rejects duplicate `name` entries and reports the duplicate class names. +- Every configured Codegeist class name resolves through the test runtime + classpath, so renamed or removed classes fail with the stale metadata entry. +- The test defines and checks the current required Codegeist-owned reflection set: + concrete config root/payload and provider/MCP dispatch types, local-tool input + records passed to Jackson, and session aggregate/part types serialized by the + session store. +- Missing required entries fail with a message that names every missing class. +- Assertions cover required constructor, field, and public-method access flags + where the current Jackson/native contract depends on them. +- The focused test and `task cli:check` pass with provider category `none`, no + Docker access, and no provider or MCP calls. + +## Files + +- `app/codegeist/cli/src/main/resources/META-INF/native-image/reflect-config.json` +- A focused test under `app/codegeist/cli/src/test/java/ai/codegeist/app/` +- Native/reflection documentation only if the test establishes a maintenance + contract not already documented + +## Non-Goals + +- Do not build a native executable; static JVM consistency is sufficient for this + task. +- Do not replace GraalVM metadata generation or prove third-party dependency + reachability. +- Do not add broad classpath scanning, architecture-test frameworks, or production + reflection registries. +- Do not add or remove runtime features merely to satisfy the metadata test. + +## Verification + +```bash +task cli:test-jvm TEST=<reflection-metadata-test-class> +DOCKER_HOST=tcp://127.0.0.1:1 task cli:check +git --no-pager diff --check +``` diff --git a/docs/tests/README.md b/docs/tests/README.md index cd0b0b8..6479ecb 100644 --- a/docs/tests/README.md +++ b/docs/tests/README.md @@ -13,27 +13,31 @@ Test guidance for Codegeist contributors and coding agents. ## Core Rules -- Use the Taskfile from `app/codegeist/cli` for implementation verification. -- Prefer `task test TEST=<selector>` for focused checks and `task test` for the - broader JVM suite. +- Use `task cli:test-jvm TEST=<selector>` from the repository root for focused + tests that must not start providers or Docker. +- Use `task cli:check` as the normal final contributor gate. It runs provider + category `none`, ignores ambient `TEST`, packages the JVM jar with + `META-INF/LICENSE`, and requires non-empty output from the real `--version` + command. - Do not document new direct `mvn test` commands for Codegeist implementation tasks unless a task explicitly needs Maven behavior that the Taskfile cannot express. -- Provider feature tests run through `task test` and method- or class-level - provider categories. `CODEGEIST_TEST_PROVIDER_CATEGORY` defaults to `none`, so - broad verification skips annotated provider calls. `task test` always starts the - fixed local Ollama service first with `OLLAMA_ENTER=false`; set the category to - `local` when local provider-call methods should run. +- Live provider feature tests run through `task cli:test` and method- or + class-level provider categories. Unlike `test-jvm`, `cli:test` starts the fixed + local Ollama service first with `OLLAMA_ENTER=false`; use it only when that setup + is intentional and set the category to `local` when local provider-call methods + should run. - Hosted provider calls require explicit `remote_free` or `remote_paid` category selection. API-key presence alone never enables hosted provider calls. -- `task mcp-remote-smoke` is the separate Docker-backed MCP `streamable_http` smoke. +- `task cli:mcp-remote-smoke` is the separate Docker-backed MCP + `streamable_http` smoke. It builds and runs a local fixture container, checks the direct MCP callback path, then checks the `ask` plus local Ollama path. It is intentionally not part of - `task test`. -- `task tui-capture-smoke` is the native TUI documentation-capture smoke. It runs + `task cli:check`. +- `task cli:tui-capture-smoke` is the native TUI documentation-capture smoke. It runs the native `codegeist tui` command through VHS with a deterministic fixture provider and writes ignored preview artifacts under `target/smoke-test`. -- `task tui-hello-world-smoke` is the native TUI hello-world video smoke. It builds +- `task cli:tui-hello-world-smoke` is the native TUI hello-world video smoke. It builds the native executable, starts a deterministic Ollama-compatible fixture provider, records the real `codegeist tui` surface through VHS as MP4/WebM, asks the TUI to create and run `hello-world.sh`, then verifies the workspace and session-store side diff --git a/docs/tests/codegeist-test-guidelines.md b/docs/tests/codegeist-test-guidelines.md index ade8074..76dce8b 100644 --- a/docs/tests/codegeist-test-guidelines.md +++ b/docs/tests/codegeist-test-guidelines.md @@ -15,33 +15,38 @@ How Codegeist tests should be shaped and reported. ## Commands -Run commands from `app/codegeist/cli` unless the task says otherwise: +Run normal contributor commands from the repository root: ```bash -task test TEST=CodegeistApplicationTests -task test TEST=CodegeistApplicationTests#contextLoads -task test +task cli:test-jvm TEST=CodegeistApplicationTests +task cli:test-jvm TEST=CodegeistApplicationTests#contextLoads +task cli:check ``` -Use task-specific selectors in active task docs and final reports. Keep broad -`task test` as the final JVM verification once focused tests pass. +Use task-specific selectors in active task docs and final reports. Keep +`task cli:check` as the final normal verification once focused tests pass. ## Provider Tests - Use `provider-feature-tests.md` as the detailed provider feature test reference. -- Keep live provider tests individually executable with `task test TEST=<selector>` - so local or hosted prerequisites remain easy to isolate. -- Broad `task test` uses the provider category default, which is `none`, and skips - annotated provider calls. It still starts the Taskfile-managed local Ollama - service before Maven. +- Keep live provider tests individually executable with + `task cli:test TEST=<selector>` so local or hosted prerequisites remain easy to + isolate. +- `task cli:test-jvm` and `task cli:check` use command-local provider category + `none`, overriding ambient values, and do not start Ollama. `task cli:check` + also ignores ambient `TEST` so it always runs the complete suite. `task cli:test` + is the explicit provider-capable path and starts the Taskfile-managed local + Ollama service before Maven. - Provider feature tests that can call providers must use method-level categories: `local`, `remote_free`, or `remote_paid`. Config-only checks stay unannotated. - `CODEGEIST_TEST_PROVIDER_CATEGORY` selects the highest provider category to run. The default is `none`; `remote_paid` is the explicit cost and rate-limit opt-in and runs all provider categories. -- Local Ollama verification uses the Taskfile-managed local Ollama instance; `task - test` starts it before every Maven test run with `OLLAMA_ENTER=false`. +- Local Ollama verification uses the Taskfile-managed local Ollama instance; + `task cli:test` starts it before Maven with `OLLAMA_ENTER=false`. - Live local Ollama tests must not pull, download, create, or delete models. +- Every provider-calling integration test, including selector-only `*IT` classes, + must carry a provider category so `test-jvm` can safely skip it under `none`. - Hosted provider calls require explicit no-cost confirmation and an opt-in task or selector. API-key presence alone is not permission to call a hosted provider. diff --git a/docs/tests/provider-feature-tests.md b/docs/tests/provider-feature-tests.md index 22fe626..502d7da 100644 --- a/docs/tests/provider-feature-tests.md +++ b/docs/tests/provider-feature-tests.md @@ -13,10 +13,11 @@ Provider tests prove three different contracts without mixing their risk levels: - Hosted provider checks prove remote provider features only after an explicit category selection and account or cost decision. -All provider verification runs through `task test` from `app/codegeist/cli`. There -is no separate provider-specific Taskfile entrypoint, no JUnit provider tag, and no -Maven group exclusion. Method-level provider categories decide whether provider-call -methods run or are skipped. +Config-only provider verification can run through `task cli:test-jvm` from the +repository root without provider setup. Live provider verification uses the +explicit `task cli:test` path. There is no provider-specific Taskfile entrypoint, +JUnit provider tag, or Maven group exclusion; method-level provider categories +decide whether provider-call methods run or are skipped. ## Implemented Feature Shape @@ -85,9 +86,9 @@ because they do not call local services or hosted APIs. | `OpenAiProviderTest` | Runs config binding and missing-API-key validation. | `remote_free` for model listing; `remote_paid` for image generation, text-to-speech, and speech-to-text. | | `OllamaProviderTest` | Runs config binding and missing-base-url validation. | `local` for one local Ollama chat call. | | `AskCommandsTest` | Skips the whole class. | `local` at class level for one Spring Boot command test backed by local Ollama. | -| `AskCommandsMcpRemoteSmokeIT` | Not included by the default Surefire test name patterns; run only by `task mcp-remote-smoke`. | `local` at class level for one Spring Boot `ask` command test backed by local Ollama plus the Docker MCP fixture. | +| `AskCommandsMcpRemoteSmokeIT` | Not included by the default Surefire test name patterns; run only by `task cli:mcp-remote-smoke`. | `local` at class level for one Spring Boot `ask` command test backed by local Ollama plus the Docker MCP fixture. | | `AskCommandsOpenAiToolSmokeIT` | Not included by the default Surefire test name patterns; run only by explicit selector. | `remote_paid` at class level for one Spring Boot `ask` command test backed by OpenAI plus local `codegeist_write`. | -| `LocalOllamaProviderIT` | Not included by the default Surefire test name patterns; run only by explicit selector. | No category gate; it is an explicit live integration test. | +| `LocalOllamaProviderIT` | Not included by the default Surefire test name patterns; an explicit `test-jvm` selector skips it. | `local` at class level; use the provider-capable `cli:test` path to run it. | ## Why These Tests Exist @@ -96,7 +97,7 @@ Provider tests are split by risk because provider work has different failure mod | Risk | Test policy | | --- | --- | | Config mapping can break ordinary startup or `--show-config`. | Config-only checks run by default under `none`. | -| Local Ollama may be unavailable, slow, or missing `llama3.2:1b`. | `task test` starts Ollama before Maven; local provider-call methods still require `CODEGEIST_TEST_PROVIDER_CATEGORY=local` or higher. | +| Local Ollama may be unavailable, slow, or missing `llama3.2:1b`. | `task cli:test` starts Ollama before Maven; local provider-call methods still require `CODEGEIST_TEST_PROVIDER_CATEGORY=local` or higher. | | Hosted APIs can consume quota, require account setup, or bill. | Hosted calls require `remote_free` or `remote_paid`; API-key presence alone is never enough. | | Paid-capable endpoints can create direct cost. | Paid-capable calls require `CODEGEIST_TEST_PROVIDER_CATEGORY=remote_paid`. | @@ -105,7 +106,7 @@ provider checks easy to run when their prerequisites are intentionally available ## When To Run Which Command -Run commands from `app/codegeist/cli`. +Run commands from the repository root. ### Ordinary Code Or Config Changes @@ -113,20 +114,21 @@ Use this for most implementation work and final JVM verification when live provi calls are not part of the task: ```bash -task test +task cli:check ``` -Why: this runs provider config checks and skips annotated provider-call methods -because the default category is `none`. It does not require Ollama, hosted -credentials, audio fixtures, or paid account confirmation. +Why: this forces provider category `none`, runs provider config checks while +skipping annotated provider-call methods, packages the JVM jar, and smokes its +real `--version` command. It does not require Ollama, Docker, hosted credentials, +audio fixtures, or paid account confirmation. ### Provider Config Parser Or Validation Changes Use focused config checks first: ```bash -task test TEST=CodegeistProviderConfigTest,CodegeistConfigServiceTest,CodegeistConfigSpelEvaluationTest -CODEGEIST_TEST_PROVIDER_CATEGORY=none task test TEST=OpenAiProviderTest,OllamaProviderTest +task cli:test-jvm TEST=CodegeistProviderConfigTest,CodegeistConfigServiceTest,CodegeistConfigSpelEvaluationTest +task cli:test-jvm TEST=OpenAiProviderTest,OllamaProviderTest ``` Why: this proves typed provider dispatch, direct YAML loading, SpEL preprocessing, @@ -139,11 +141,12 @@ Use this when the task changes `OllamaProviderConfig`, `OllamaChatModel`, `CodegeistChatService`, `CodegeistChatRequest`, or local Ollama provider behavior: ```bash -CODEGEIST_TEST_PROVIDER_CATEGORY=local task test TEST=OllamaProviderTest +CODEGEIST_TEST_PROVIDER_CATEGORY=local task cli:test TEST=OllamaProviderTest ``` -Why: `task test` automatically runs `ollama-start` with `OLLAMA_ENTER=false` before -Maven. `ollama-start` starts or reuses the local `codegeist-ollama` container and +Why: `task cli:test` automatically runs `ollama-start` with +`OLLAMA_ENTER=false` before Maven. `ollama-start` starts or reuses the local +`codegeist-ollama` container and ensures the selected model is present, while the focused test proves config loading plus the provider feature chat method. The Java test uses fixed values and does not pull models itself: @@ -157,7 +160,7 @@ Use this broader local check only when local provider behavior should be include in the whole JVM suite: ```bash -CODEGEIST_TEST_PROVIDER_CATEGORY=local task test +CODEGEIST_TEST_PROVIDER_CATEGORY=local task cli:test ``` Why: `local` also allows every lower category, so it runs unannotated config checks @@ -169,15 +172,18 @@ Use this when the task specifically changes the provider-neutral chat seam or Sp application context path used by local provider calls: ```bash -CODEGEIST_TEST_PROVIDER_CATEGORY=local task test TEST=LocalOllamaProviderIT +CODEGEIST_TEST_PROVIDER_CATEGORY=local task cli:test TEST=LocalOllamaProviderIT ``` -Why: `task test` starts Ollama first, and the `local` category documents that this +Why: `task cli:test` starts Ollama first, and the `local` category documents that this selector intentionally exercises the local provider path. `LocalOllamaProviderIT` starts `CodegeistApplication` through a manual Spring application builder, loads a temporary `codegeist.yml`, and calls `CodegeistChatService` with a selected `ProviderConfig` plus runtime model and prompt. It is intentionally selector-only -and not part of broad `task test`. +and not part of `task cli:check`. + +Selecting this class through `task cli:test-jvm TEST=LocalOllamaProviderIT` keeps +the forced `none` category and skips the class without contacting Ollama. ### Ask Plus Remote MCP Smoke @@ -186,7 +192,7 @@ Use this when the task changes MCP callback wiring, local Ollama tool-calling, o Docker MCP fixture URL and local Ollama startup are prepared together: ```bash -task mcp-remote-smoke +task cli:mcp-remote-smoke ``` Why: this first proves the direct `streamable_http` MCP callback path, then runs @@ -201,7 +207,7 @@ Use this only after recording or confirming that the selected account, endpoint, model, and route are no-cost for the current run: ```bash -CODEGEIST_TEST_PROVIDER_CATEGORY=remote_free task test TEST=OpenAiProviderTest#testListModels +CODEGEIST_TEST_PROVIDER_CATEGORY=remote_free task cli:test TEST=OpenAiProviderTest#testListModels ``` Why: `remote_free` is for explicitly selected no-cost hosted calls. It still @@ -215,9 +221,9 @@ Use this only after an explicit cost and rate-limit decision for the selected account and endpoint: ```bash -CODEGEIST_TEST_PROVIDER_CATEGORY=remote_paid task test TEST=OpenAiProviderTest#testImageGeneration -CODEGEIST_TEST_PROVIDER_CATEGORY=remote_paid task test TEST=OpenAiProviderTest#testTextToSpeech -CODEGEIST_TEST_PROVIDER_CATEGORY=remote_paid task test TEST=OpenAiProviderTest#testSpeechToText +CODEGEIST_TEST_PROVIDER_CATEGORY=remote_paid task cli:test TEST=OpenAiProviderTest#testImageGeneration +CODEGEIST_TEST_PROVIDER_CATEGORY=remote_paid task cli:test TEST=OpenAiProviderTest#testTextToSpeech +CODEGEIST_TEST_PROVIDER_CATEGORY=remote_paid task cli:test TEST=OpenAiProviderTest#testSpeechToText ``` Why: `remote_paid` allows paid-capable calls. Prefer method selectors so the run is @@ -232,7 +238,7 @@ Use this only after an explicit cost and rate-limit decision for the selected Op account and model: ```bash -CODEGEIST_TEST_PROVIDER_CATEGORY=remote_paid task test TEST=AskCommandsOpenAiToolSmokeIT +CODEGEIST_TEST_PROVIDER_CATEGORY=remote_paid task cli:test TEST=AskCommandsOpenAiToolSmokeIT ``` Why: this runs one Spring Boot `ask` command through `OpenAiChatModel`, exposes the @@ -250,7 +256,7 @@ implemented OpenAI provider feature test: ```bash CODEGEIST_TEST_OPENAI_APIKEY=... \ CODEGEIST_TEST_PROVIDER_CATEGORY=remote_paid \ -task test TEST=OpenAiProviderTest +task cli:test TEST=OpenAiProviderTest ``` Why: this runs all six `OpenAiProviderTest` methods: two unannotated config checks, @@ -270,7 +276,7 @@ environment: ```text CODEGEIST_TEST_OPENAI_APIKEY=<set in the environment> CODEGEIST_TEST_PROVIDER_CATEGORY=remote_paid -task test TEST=AskCommandsOpenAiToolSmokeIT +task cli:test TEST=AskCommandsOpenAiToolSmokeIT ``` Result: @@ -351,11 +357,11 @@ Provider tests intentionally produce skipped methods in safe runs: | Command | Expected provider-call behavior | | --- | --- | -| `task test` | Starts Ollama before Maven, then skips annotated provider-call methods because the category is `none`. | -| `CODEGEIST_TEST_PROVIDER_CATEGORY=none task test TEST=OpenAiProviderTest,OllamaProviderTest` | Same as broad default, but limited to provider feature classes. | -| `CODEGEIST_TEST_PROVIDER_CATEGORY=local task test TEST=OllamaProviderTest` | Ollama config checks and local chat run; no methods should be skipped in this class when Ollama is ready. | -| `CODEGEIST_TEST_PROVIDER_CATEGORY=remote_free task test TEST=OpenAiProviderTest#testListModels` | The selected method runs; missing required hosted inputs fail the test. | -| `CODEGEIST_TEST_PROVIDER_CATEGORY=remote_paid task test TEST=OpenAiProviderTest#testSpeechToText` | The selected paid-capable method runs; missing credentials fail the test, and the audio fixture is generated if missing. | +| `task cli:check` | Forces category `none`, runs no provider calls, packages the jar, and smokes `--version` without Ollama or Docker. | +| `task cli:test-jvm TEST=OpenAiProviderTest,OllamaProviderTest` | Runs config-only methods and skips provider-call methods without starting Ollama. | +| `CODEGEIST_TEST_PROVIDER_CATEGORY=local task cli:test TEST=OllamaProviderTest` | Ollama config checks and local chat run; no methods should be skipped in this class when Ollama is ready. | +| `CODEGEIST_TEST_PROVIDER_CATEGORY=remote_free task cli:test TEST=OpenAiProviderTest#testListModels` | The selected method runs; missing required hosted inputs fail the test. | +| `CODEGEIST_TEST_PROVIDER_CATEGORY=remote_paid task cli:test TEST=OpenAiProviderTest#testSpeechToText` | The selected paid-capable method runs; missing credentials fail the test, and the audio fixture is generated if missing. | Skipped provider-call methods under `none` are not failures. They are the safety contract that keeps ordinary verification free from local-provider calls and @@ -406,7 +412,7 @@ Use this checklist when adding future provider feature tests: | `app/codegeist/cli/src/test/java/ai/codegeist/app/provider/OllamaProviderTest.java` | Config checks and local Ollama provider feature test. | | `app/codegeist/cli/src/test/java/ai/codegeist/app/provider/OpenAiProviderTest.java` | Config checks and hosted OpenAI provider feature tests. | | `app/codegeist/cli/src/test/java/ai/codegeist/app/provider/AskCommandsTest.java` | Spring Boot command test gated as a local provider-call class. | -| `app/codegeist/cli/src/test/java/ai/codegeist/app/provider/AskCommandsMcpRemoteSmokeIT.java` | Explicit local Ollama plus Docker MCP fixture command smoke driven by `task mcp-remote-smoke`. | +| `app/codegeist/cli/src/test/java/ai/codegeist/app/provider/AskCommandsMcpRemoteSmokeIT.java` | Explicit local Ollama plus Docker MCP fixture command smoke driven by `task cli:mcp-remote-smoke`. | | `app/codegeist/cli/src/test/java/ai/codegeist/app/chat/LocalOllamaProviderIT.java` | Explicit local provider-neutral integration seam test. | | `docs/developer/architecture/provider-configuration.md` | Current-state provider config architecture. | | `docs/developer/specification/llm-provider-implementation.md` | Provider runtime and future provider implementation guidance. | diff --git a/docs/tests/smoke-tests.md b/docs/tests/smoke-tests.md index f8e2e74..86be807 100644 --- a/docs/tests/smoke-tests.md +++ b/docs/tests/smoke-tests.md @@ -228,8 +228,9 @@ Labels should be stable and specific, for example: - Native archive smokes run through `scripts/tests/artifact-smoke.ps1`. The harness packages native artifacts as `target/dist/codegeist-<platform>.<extension>`, - unpacks native archives into a temporary directory, verifies `--version`, verifies - native `--show-config`, and checks non-empty command logs. + copies the canonical root `LICENSE`, unpacks native archives into a temporary + directory, hash-compares the packaged license with the source, verifies + `--version`, verifies native `--show-config`, and checks non-empty command logs. - File-edit artifact smokes are invoked by `artifact-smoke.ps1` through `scripts/tests/file-edit-ask-smoke.ps1`. The sub-harness starts a deterministic local Ollama-compatible fixture provider, runs the artifact's real `ask` command, diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 0000000..ab85de7 --- /dev/null +++ b/examples/README.md @@ -0,0 +1,33 @@ +# Codegeist Configuration Examples + +These examples are small parser-checked starting points for the currently +implemented direct `codegeist.yml` roots. Copy only the settings you need into a +local `codegeist.yml`; Codegeist does not load files from `examples/` +automatically. + +- `codegeist.ollama.yml` configures a local Ollama endpoint and model. +- `codegeist.openai.yml` uses the literal non-credential placeholder + `not-a-real-openai-api-key` so production validation accepts the tracked example + without reading the environment. +- `codegeist.mcp.yml` defines a local stdio MCP filesystem server. Using it can + start the configured child process and may let `npx` download the package. + +The files contain no usable credentials and parser tests make no provider or MCP +calls. Replace placeholders only in ignored local configuration, never in these +tracked examples. + +## Trust Boundaries + +Treat `codegeist.yml` as trusted local code: string values containing `#{...}` +use an unrestricted Spring SpEL evaluation context. `--show-config` prints +configured values without redaction. Codegeist tools can read, write, edit, and +run host processes, and current workspace controls are not a sandbox or a +permission-prompt system. Review configuration and tool access before running +`ask` or `tui` in a sensitive workspace. + +To prove the examples still match the production parser without starting +providers, run from the repository root: + +```bash +task cli:test-jvm TEST=CodegeistExamplesTest +``` diff --git a/examples/codegeist.mcp.yml b/examples/codegeist.mcp.yml new file mode 100644 index 0000000..8cbfcd9 --- /dev/null +++ b/examples/codegeist.mcp.yml @@ -0,0 +1,8 @@ +mcp: + filesystem: + type: stdio + command: npx + args: + - -y + - "@modelcontextprotocol/server-filesystem" + - . diff --git a/examples/codegeist.ollama.yml b/examples/codegeist.ollama.yml new file mode 100644 index 0000000..b8d869b --- /dev/null +++ b/examples/codegeist.ollama.yml @@ -0,0 +1,6 @@ +provider: + local-ollama: + type: ollama + name: Local Ollama + base-url: http://localhost:11434 + model: llama3.2:1b diff --git a/examples/codegeist.openai.yml b/examples/codegeist.openai.yml new file mode 100644 index 0000000..60d91b2 --- /dev/null +++ b/examples/codegeist.openai.yml @@ -0,0 +1,5 @@ +provider: + openai: + type: openai + name: OpenAI + api-key: not-a-real-openai-api-key diff --git a/scripts/tests/artifact-smoke.ps1 b/scripts/tests/artifact-smoke.ps1 index c29c683..19ea7a8 100644 --- a/scripts/tests/artifact-smoke.ps1 +++ b/scripts/tests/artifact-smoke.ps1 @@ -10,6 +10,7 @@ # Inputs: # - Platform: `linux-x64`, `windows-x64`, or `macos-x64`. # - CliDir: app/codegeist/cli directory containing target/ build outputs. +# - LicenseFile: canonical repository LICENSE copied into every native archive. # - WindowsVcRedistDir: MSVC `VCToolsRedistDir`; required for Windows archives # so the app-local CRT is packaged beside codegeist.exe. # - Ask-driven tool smokes use deterministic fixture providers so real model wording @@ -44,6 +45,8 @@ param( [string]$ShellAskSmokeScript = "", + [string]$LicenseFile = "", + [int]$NativeTimeoutSeconds = 5, [int]$FileEditTimeoutSeconds = 90, @@ -314,6 +317,21 @@ function Assert-WindowsVcRuntime { } } +function Assert-PackagedLicense { + param([string]$Directory) + + $packagedLicense = Join-Path $Directory "LICENSE" + if (-not (Test-Path -LiteralPath $packagedLicense -PathType Leaf)) { + Fail-Smoke "Canonical LICENSE was not packaged: $packagedLicense" + } + + $sourceHash = (Get-FileHash -LiteralPath $LicenseFile -Algorithm SHA256).Hash + $packagedHash = (Get-FileHash -LiteralPath $packagedLicense -Algorithm SHA256).Hash + if ($packagedHash -ne $sourceHash) { + Fail-Smoke "Packaged LICENSE does not match the repository LICENSE: $packagedLicense" + } +} + function New-NativeArchive { $binaryName = Get-NativeBinaryName $native = if ($NativeExecutable) { Resolve-SmokePath $NativeExecutable } else { Join-Path $CliDir "target/$binaryName" } @@ -342,6 +360,7 @@ function New-NativeArchive { Copy-NativeSidecars $packageDir Copy-WindowsVcRuntime $packageDir + Copy-Item -LiteralPath $LicenseFile -Destination (Join-Path $packageDir "LICENSE") -Force $stopwatch = [System.Diagnostics.Stopwatch]::StartNew() if ($extension -eq "zip") { @@ -396,6 +415,7 @@ function Invoke-NativeArtifactSmoke { Fail-Smoke "Packaged native executable was not found after unpack: $native" } Assert-WindowsVcRuntime $runDir + Assert-PackagedLicense $runDir Write-SmokeLog "Command: $native --version" Invoke-SmokeProcess ` @@ -449,6 +469,14 @@ if (-not (Test-Path -LiteralPath $CliDir)) { Fail-Smoke "CLI module directory not found: $CliDir" } +if (-not $LicenseFile) { + $LicenseFile = Join-Path $CliDir "../../../LICENSE" +} +$LicenseFile = Resolve-SmokePath $LicenseFile +if (-not (Test-Path -LiteralPath $LicenseFile -PathType Leaf)) { + Fail-Smoke "Canonical repository LICENSE not found: $LicenseFile" +} + if (-not $DistDir) { $DistDir = Join-Path $CliDir "target/dist" }