Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
3fe31d7
refactor(core): migrate to dappco.re/go v0.9.0 API
Snider Apr 28, 2026
a43663c
refactor(core): adopt Ok/Fail/ResultOf constructors over Result literals
Snider Apr 28, 2026
cee6899
refactor(core): full v0.9.0 compliance against core/go reference
Snider Apr 28, 2026
0020cb4
ci: woodpecker pipeline (Go) — golangci-lint/eslint/phpstan + sonar.l…
Snider Apr 28, 2026
e669a5d
ci: woodpecker pipeline (Go) — golangci-lint/eslint/phpstan + sonar.l…
Snider Apr 28, 2026
212d272
refactor(core): align api with v0.9.1 hardened core/go reference shape
Snider Apr 29, 2026
433039c
refactor(core): api round 2 — full 24-dim COMPLIANT
Snider Apr 29, 2026
2bf28fb
refactor(api): drop unused internal/compat/{core,miner} shims
Snider Apr 30, 2026
620d99c
refactor(api): morph back to registry-shape — strip stdcompat shims, …
Snider Apr 30, 2026
12e8328
chore(api): rename src/ to php/ and clean up stale .md files
Snider Apr 30, 2026
5776423
chore(api): restructure Go module under go/ for cross-language symmetry
Snider Apr 30, 2026
3521e2f
feat(api): add go.work + external/ submodules for dev workspace mode
Snider Apr 30, 2026
fd06ecd
chore(lint): clear production-side errcheck/staticcheck
Snider Apr 30, 2026
be17f34
ci: add SonarCloud + Codecov uploaders alongside lthn.sh sonar
Snider Apr 30, 2026
8ab1cc8
ci(github): add public CI workflow (test + lint + sonarcloud + codecov)
Snider Apr 30, 2026
3a89774
docs(README): rewrite with public CI + sonarcloud + codecov badges
Snider Apr 30, 2026
49b659a
ci(github): set GOPROXY=direct + GOSUMDB=off to match Woodpecker
Snider Apr 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
Empty file removed .core/TODO.md
Empty file.
80 changes: 80 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
name: CI

on:
push:
branches: [dev, main]
pull_request:
branches: [dev, main]

permissions:
contents: read

env:
GOFLAGS: -buildvcs=false
GOWORK: "off"
GOPROXY: "direct"
GOSUMDB: "off"

jobs:
test:
name: Test + Coverage
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0
- uses: actions/setup-go@v6
with:
go-version: '1.26'
- name: Test with coverage
working-directory: go
run: go test -race -coverprofile=coverage.out -covermode=atomic -count=1 ./...
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: go/coverage.out
flags: unittests
fail_ci_if_error: false

lint:
name: golangci-lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/setup-go@v6
with:
go-version: '1.26'
- uses: golangci/golangci-lint-action@v9
with:
version: latest
working-directory: go
args: --timeout=5m --tests=false

sonarcloud:
name: SonarCloud
runs-on: ubuntu-latest
needs: test
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0
- uses: actions/setup-go@v6
with:
go-version: '1.26'
- name: Test for coverage
working-directory: go
run: go test -coverprofile=coverage.out -covermode=atomic -count=1 ./...
- name: SonarCloud Scan
uses: SonarSource/sonarqube-scan-action@v6
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
with:
args: >
-Dsonar.organization=dappcore
-Dsonar.projectKey=dappcore_api
-Dsonar.sources=go
-Dsonar.exclusions=**/vendor/**,**/third_party/**,**/.tmp/**,**/*_test.go
-Dsonar.tests=go
-Dsonar.test.inclusions=**/*_test.go
-Dsonar.go.coverage.reportPaths=go/coverage.out
32 changes: 32 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[submodule "external/go"]
path = external/go
url = https://github.com/dappcore/go.git
branch = dev
[submodule "external/go-process"]
path = external/go-process
url = https://github.com/dappcore/go-process.git
branch = dev
[submodule "external/go-scm"]
path = external/go-scm
url = https://github.com/dappcore/go-scm.git
branch = dev
[submodule "external/go-proxy"]
path = external/go-proxy
url = https://github.com/dappcore/go-proxy.git
branch = dev
[submodule "external/go-ws"]
path = external/go-ws
url = https://github.com/dappcore/go-ws.git
branch = dev
[submodule "external/go-inference"]
path = external/go-inference
url = https://github.com/dappcore/go-inference.git
branch = dev
[submodule "external/go-io"]
path = external/go-io
url = https://github.com/dappcore/go-io.git
branch = dev
[submodule "external/go-log"]
path = external/go-log
url = https://github.com/dappcore/go-log.git
branch = dev
62 changes: 62 additions & 0 deletions .woodpecker.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Woodpecker CI pipeline.
# Server: ci.lthn.sh.
# Lint + test run in parallel; sonar (lthn.sh + sonarcloud) + codecov fan
# out from go-test.

when:
- event: [push, manual, tag]
branch: [dev, main]

steps:
- name: golangci-lint
image: golangci/golangci-lint:latest-alpine
depends_on: []
environment:
GOFLAGS: -buildvcs=false
GOWORK: "off"
commands:
- cd go && golangci-lint run --timeout=5m ./...

- name: go-test
image: golang:1.26-alpine
depends_on: []
environment:
GOFLAGS: -buildvcs=false
GOWORK: "off"
CGO_ENABLED: "1"
commands:
- apk add --no-cache git build-base
- cd go && go test -race -coverprofile=coverage.out -covermode=atomic -count=1 ./...

- name: sonar-internal
image: sonarsource/sonar-scanner-cli:latest
depends_on: [go-test]
environment:
SONAR_HOST_URL: https://sonar.lthn.sh
SONAR_TOKEN:
from_secret: sonar_token
commands:
- sonar-scanner

- name: sonarcloud
image: sonarsource/sonar-scanner-cli:latest
depends_on: [go-test]
environment:
SONAR_TOKEN:
from_secret: sonarcloud_token
commands:
- sonar-scanner
-Dsonar.host.url=https://sonarcloud.io
-Dsonar.organization=dappcore
-Dsonar.projectKey=dappcore_api
-Dsonar.go.coverage.reportPaths=go/coverage.out

- name: codecov
image: alpine:3.20
depends_on: [go-test]
environment:
CODECOV_TOKEN:
from_secret: codecov_token
commands:
- apk add --no-cache curl bash git
- cd go && bash <(curl -s https://codecov.io/bash) -f coverage.out -t "$CODECOV_TOKEN" -F unittests
52 changes: 52 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<!-- SPDX-License-Identifier: EUPL-1.2 -->

# Agent Notes

This repository is the Go Core API framework. Treat it as infrastructure: keep
changes narrow, preserve the public `RouteGroup` and `Engine` contracts, and
verify the whole module before handing work back.

## Code Map

- `api.go` owns `Engine`, route group registration, handler construction, and
graceful serving.
- `options.go` contains public `With*` options. New middleware should enter
through this file unless it is strictly internal.
- `response.go`, `middleware.go`, `authentik.go`, `sse.go`, `websocket.go`,
`graphql.go`, `swagger.go`, `openapi.go`, `export.go`, and `codegen.go`
implement the user-facing HTTP features.
- `bridge.go` maps `ToolDescriptor` values to REST endpoints and OpenAPI
descriptions.
- `cmd/api` wires Core CLI actions for spec export and SDK generation.
- `cmd/gateway` builds the provider gateway binary.
- `pkg/provider` contains provider discovery, registry, and reverse proxy
support.
- `pkg/stream` contains declarative stream route groups.

## Compliance Rules

Follow the v0.9.0 Core compliance shape. Use `dappco.re/go` wrappers for JSON,
errors, formatting, strings, buffers, filesystem, process, and environment
helpers whenever a wrapper exists. Do not add files named `ax7*.go`, versioned
test files, or monolithic compliance dumps.

For every production source file with public symbols, keep tests and examples
beside that file. Test names use `Test<File>_<Symbol>_Good`,
`Test<File>_<Symbol>_Bad`, and `Test<File>_<Symbol>_Ugly`. Examples use
`Example<Symbol>` or a valid lowercase suffix variant and print through Core
`Println`.

## Before Stopping

Use the exact repository gate, with `GOWORK=off` for Go commands:

```bash
GOWORK=off go mod tidy
GOWORK=off go vet ./...
GOWORK=off go test -count=1 ./...
gofmt -l .
bash /Users/snider/Code/core/go/tests/cli/v090-upgrade/audit.sh .
```

If the sandbox cannot write the default Go build cache, set `GOCACHE` to a
temporary directory while running the same commands.
63 changes: 56 additions & 7 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,56 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co

Core API is the REST framework for the Lethean ecosystem, providing both a **Go HTTP engine** (Gin-based, with OpenAPI generation, WebSocket/SSE, ToolBridge) and a **PHP Laravel package** (rate limiting, webhooks, API key management, OpenAPI documentation). Both halves serve the same purpose in their respective stacks.

Module: `dappco.re/go/core/api` | Package: `dappco.re/php/service` | Licence: EUPL-1.2
Module: `dappco.re/go/api` | Package: `dappco.re/php/service` | Licence: EUPL-1.2

## Repo Layout

```
core/api/
├── go.work ← workspace root (one level above the module)
├── external/<dappco.re-go-dep>/ ← git submodules tracking dev branches on github
├── go/ ← Go module root (module dappco.re/go/api)
├── php/ ← PHP package
├── docs/ ← engine docs (symlinked from go/)
├── sdk-config/ ← cross-language SDK gen configs
└── scripts/ ← cross-language build helpers
```
Comment on lines +13 to +22
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add language specifier to fenced code block.

The code block should specify a language identifier for proper rendering and tooling support.

📝 Proposed fix
-```
+```text
 core/api/
 ├── go.work                            ← workspace root (one level above the module)
 ├── external/<dappco.re-go-dep>/       ← git submodules tracking dev branches on github
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 13-13: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@CLAUDE.md` around lines 13 - 22, Add a language identifier to the fenced code
block that contains the directory tree (the triple-backtick block surrounding
the "core/api/" tree) so tooling renders it correctly; replace the opening ```
with ```text (or another appropriate language) to specify the language for that
fenced code block.


Cross-language symmetry target: `dappco.re/<lang>/api/<feature>` ↔ `core/api/<lang>/<feature>` (Go today, PHP today, TS+Py later).

## Go Resolution Modes

Two ways the same `go/go.mod` resolves dappco.re/go/* deps:

| Mode | When | What runs |
|------|------|-----------|
| **Workspace ON** (default for devs) | `go build` / `go test` from any subdir of `core/api/` | Walks up to `go.work`, uses local `external/<x>` checkouts at submodule pin (typically dev tip). Fast iteration; finds upstream bugs early. |
| **`GOWORK=off`** | Woodpecker CI | Pure go.mod, fetches the pinned tag from the proxy. Reproducible builds. No replace directives — 0% policy intact. |

### Working with submodules

```bash
git clone --recursive https://github.com/dappcore/api.git # full dev workspace
git submodule update --init --recursive # if cloned without --recursive

# Bump a single dep to its current dev tip
git submodule update --remote external/go-process

# See latest tag in a dep
( cd external/go-process && git tag --sort=-v:refname | head )

# When ready to bump the api go.mod to that dep's new tag
( cd go && go get dappco.re/go/process@v0.11.0 && go mod tidy )
```

### Workspace mode caveat

Workspace mode validates each `external/<x>/go.sum` against current proxy bits. If an upstream repo has a stale or missing go.sum entry, the build errors with `verifying ...: checksum mismatch`. Two ways to handle:

1. **Fix upstream**: `cd external/<x> && go mod tidy`, commit + push to that repo's dev, then `git submodule update --remote external/<x>` here.
2. **CI mode locally**: `GOWORK=off go test ./go/...` — uses the api repo's pinned hashes.

This is the "find bugs as they roll out" payoff: workspace mode surfaces stale-sum issues across the whole tree.

## Build and Test Commands

Expand Down Expand Up @@ -36,7 +85,7 @@ composer lint # Laravel Pint (PSR-12)
./vendor/bin/pint --dirty # Format changed files
```

Tests live in `src/php/src/Api/Tests/Feature/` (in-source) and `src/php/tests/` (standalone).
Tests live in `php/src/Api/Tests/Feature/` (in-source) and `php/tests/` (standalone).

## Architecture

Expand All @@ -63,15 +112,15 @@ engine.Serve(ctx)

**CLI** (`cmd/api/`): Registers `core api spec` and `core api sdk` commands.

### PHP Package (`src/php/`)
### PHP Package (`php/`)

Three namespace roots:

| Namespace | Path | Role |
|-----------|------|------|
| `Core\Front\Api` | `src/php/src/Front/Api/` | API frontage — middleware, versioning, auto-discovered provider |
| `Core\Api` | `src/php/src/Api/` | Backend — auth, scopes, models, webhooks, OpenAPI docs |
| `Core\Website\Api` | `src/php/src/Website/Api/` | Documentation UI — controllers, Blade views, web routes |
| `Core\Front\Api` | `php/src/Front/Api/` | API frontage — middleware, versioning, auto-discovered provider |
| `Core\Api` | `php/src/Api/` | Backend — auth, scopes, models, webhooks, OpenAPI docs |
| `Core\Website\Api` | `php/src/Website/Api/` | Documentation UI — controllers, Blade views, web routes |

Boot chain: `Front\Api\Boot` (auto-discovered) fires `ApiRoutesRegistering` -> `Api\Boot` registers middleware and routes.

Expand All @@ -93,7 +142,7 @@ Key services: `WebhookService`, `RateLimitService`, `IpRestrictionService`, `Ope

| Go module | Role |
|-----------|------|
| `dappco.re/go/core/cli` | CLI command registration |
| `dappco.re/go/cli` | CLI command registration for the nested `cmd/api` module |
| `github.com/gin-gonic/gin` | HTTP router |
| `github.com/casbin/casbin/v2` | Authorisation policies |
| `github.com/coreos/go-oidc/v3` | OIDC / Authentik |
Expand Down
Loading
Loading