Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions .beads-sdp-mapping.jsonl
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{"sdp_id":"00-001-01","beads_id":"sdp_dev-8gt","updated_at":"2026-02-22T20:18:42.000Z"}
{"sdp_id":"00-001-02","beads_id":"sdp_dev-p3y","updated_at":"2026-02-22T20:18:42.000Z"}
{"sdp_id":"00-002-01","beads_id":"sdp_dev-63h","updated_at":"2026-02-22T20:18:42.000Z"}
{"sdp_id":"00-002-02","beads_id":"sdp_dev-y2h","updated_at":"2026-02-22T20:18:42.000Z"}
{"sdp_id":"00-002-03","beads_id":"sdp_dev-1gh","updated_at":"2026-02-22T20:18:42.000Z"}
{"sdp_id":"00-003-01","beads_id":"sdp_dev-0o2","updated_at":"2026-02-22T22:00:00.000Z"}
{"sdp_id":"00-003-02","beads_id":"sdp_dev-3xi","updated_at":"2026-02-22T22:00:00.000Z"}
{"sdp_id":"00-004-01","beads_id":"sdp_dev-uyn","updated_at":"2026-02-22T22:00:00.000Z"}
{"sdp_id":"00-004-02","beads_id":"sdp_dev-45l","updated_at":"2026-02-22T22:00:00.000Z"}
{"sdp_id":"00-004-03","beads_id":"sdp_dev-5jb","updated_at":"2026-02-22T22:00:00.000Z"}
{"sdp_id":"00-005-01","beads_id":"sdp_dev-6mi","updated_at":"2026-02-22T22:00:00.000Z"}
{"sdp_id":"00-006-01","beads_id":"sdp_dev-dcq","updated_at":"2026-02-22T22:00:00.000Z"}
{"sdp_id":"00-006-02","beads_id":"sdp_dev-e5n","updated_at":"2026-02-22T22:00:00.000Z"}
{"sdp_id":"00-007-01","beads_id":"sdp_dev-qet","updated_at":"2026-02-22T22:00:00.000Z"}
{"sdp_id":"00-007-02","beads_id":"sdp_dev-5xd","updated_at":"2026-02-22T22:00:00.000Z"}
{"sdp_id":"00-008-01","beads_id":"sdp_dev-9661","updated_at":"2026-02-22T22:00:00.000Z"}
{"sdp_id":"00-008-02","beads_id":"sdp_dev-dlok","updated_at":"2026-02-22T22:00:00.000Z"}
{"sdp_id":"00-009-01","beads_id":"sdp_dev-ktfr","updated_at":"2026-02-22T22:00:00.000Z"}
{"sdp_id":"00-009-02","beads_id":"sdp_dev-bxfn","updated_at":"2026-02-22T22:00:00.000Z"}
{"sdp_id":"00-010-01","beads_id":"sdp_dev-5ngw","updated_at":"2026-02-22T22:00:00.000Z"}
{"sdp_id":"00-011-01","beads_id":"sdp_dev-5cn2","updated_at":"2026-02-22T22:00:00.000Z"}
{"sdp_id":"00-011-02","beads_id":"sdp_dev-lb2p","updated_at":"2026-02-22T22:00:00.000Z"}
{"sdp_id":"00-012-01","beads_id":"sdp_dev-yall","updated_at":"2026-02-22T22:00:00.000Z"}
{"sdp_id":"00-013-01","beads_id":"sdp_dev-l6xx","updated_at":"2026-02-22T22:00:00.000Z"}
{"sdp_id":"00-013-02","beads_id":"sdp_dev-7ms2","updated_at":"2026-02-22T22:00:00.000Z"}
{"sdp_id":"00-013-03","beads_id":"sdp_dev-x9j1","updated_at":"2026-02-22T22:00:00.000Z"}
{"sdp_id":"00-014-01","beads_id":"sdp_dev-u7db","updated_at":"2026-02-23T12:00:00.000Z"}
{"sdp_id":"00-014-02","beads_id":"sdp_dev-3vtt","updated_at":"2026-02-23T12:00:00.000Z"}
{"sdp_id":"00-015-01","beads_id":"sdp_dev-jt9x","updated_at":"2026-02-23T12:00:00.000Z"}
{"sdp_id":"00-015-02","beads_id":"sdp_dev-3l1m","updated_at":"2026-02-23T12:00:00.000Z"}
{"sdp_id":"00-016-01","beads_id":"sdp_dev-kvsi","updated_at":"2026-02-23T12:00:00.000Z"}
{"sdp_id":"00-016-02","beads_id":"sdp_dev-dhip","updated_at":"2026-02-23T12:00:00.000Z"}
{"sdp_id":"00-016-03","beads_id":"sdp_dev-yxql","updated_at":"2026-02-23T12:00:00.000Z"}
{"sdp_id":"00-017-01","beads_id":"sdp_dev-8n59","updated_at":"2026-02-23T12:00:00.000Z"}
{"sdp_id":"00-017-02","beads_id":"sdp_dev-iv35","updated_at":"2026-02-23T12:00:00.000Z"}
{"sdp_id":"00-018-01","beads_id":"sdp_dev-mfs9","updated_at":"2026-02-23T12:00:00.000Z"}
{"sdp_id":"00-018-02","beads_id":"sdp_dev-7a1a","updated_at":"2026-02-23T12:00:00.000Z"}
{"sdp_id":"00-018-03","beads_id":"sdp_dev-tivd","updated_at":"2026-02-23T20:00:00.000Z"}
{"sdp_id":"00-019-01","beads_id":"sdp_dev-b5hl","updated_at":"2026-02-23T12:00:00.000Z"}
{"sdp_id":"00-019-02","beads_id":"sdp_dev-hbum","updated_at":"2026-02-23T12:00:00.000Z"}
{"sdp_id":"00-019-03","beads_id":"sdp_dev-0fld","updated_at":"2026-02-23T12:00:00.000Z"}
{"sdp_id":"00-020-01","beads_id":"sdp_dev-s8ky","updated_at":"2026-02-23T12:00:00.000Z"}
{"sdp_id":"00-016-04","beads_id":"sdp_dev-5xsz","updated_at":"2026-02-23T12:08:00.000Z"}
{"sdp_id":"00-021-01","beads_id":"sdp_dev-ap8x","updated_at":"2026-02-23T13:00:00.000Z"}
{"sdp_id":"00-022-01","beads_id":"sdp_dev-bdwr","updated_at":"2026-02-23T19:00:00.000Z"}
{"sdp_id":"00-023-01","beads_id":"sdp_dev-tisy","updated_at":"2026-02-23T19:00:00.000Z"}
{"sdp_id":"00-023-02","beads_id":"sdp_dev-h3y5","updated_at":"2026-02-23T19:00:00.000Z"}
{"sdp_id":"00-024-01","beads_id":"sdp_dev-bl3s","updated_at":"2026-02-23T19:00:00.000Z"}
{"sdp_id":"00-025-01","beads_id":"sdp_dev-h7qu","updated_at":"2026-02-23T19:00:00.000Z"}
{"sdp_id":"00-026-01","beads_id":"sdp_dev-5pl6","updated_at":"2026-02-23T19:00:00.000Z"}
{"sdp_id":"00-027-01","beads_id":"sdp_dev-78hc","updated_at":"2026-02-23T19:00:00.000Z"}
{"sdp_id":"00-028-01","beads_id":"sdp_dev-jd2q","updated_at":"2026-02-23T00:00:00.000Z"}
{"sdp_id":"00-029-01","beads_id":"sdp_dev-w69o","updated_at":"2026-02-23T00:00:00.000Z"}
{"sdp_id":"00-030-01","beads_id":"sdp_dev-tsi6","updated_at":"2026-02-23T00:00:00.000Z"}
2 changes: 2 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Exclude .beads so E2E gets fresh sqlite init (host may have dolt/daemon state)
.beads/
16 changes: 16 additions & 0 deletions .github/workflows/go-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,23 @@ permissions:
attestations: write

jobs:
protocol-e2e:
name: Protocol E2E
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Protocol E2E (Docker)
env:
GLM_API_KEY: ${{ secrets.GLM_API_KEY }}
run: |
docker build -f ci/Dockerfile.protocol-e2e -t sdp-protocol-e2e:latest .
docker run --rm -e GLM_API_KEY="${GLM_API_KEY}" sdp-protocol-e2e:latest

release:
needs: protocol-e2e
name: Release with GoReleaser
runs-on: ubuntu-latest
defaults:
Expand Down
37 changes: 37 additions & 0 deletions .github/workflows/protocol-e2e.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Protocol E2E - full SDP protocol test before release
# Runs on PR and tag push; required before release
name: Protocol E2E

on:
pull_request:
branches: [main, dev]
paths:
- "cmd/**"
- "internal/**"
- "sdp-plugin/**"
- "docs/workstreams/**"
- ".beads-sdp-mapping.jsonl"
- "ci/**"
- "schema/**"

permissions:
contents: read

jobs:
protocol-e2e:
name: Protocol E2E (Docker)
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Protocol E2E (Docker)
env:
GLM_API_KEY: ${{ secrets.GLM_API_KEY }}
run: |
docker build -f ci/Dockerfile.protocol-e2e -t sdp-protocol-e2e:latest .
docker run --rm \
-e GLM_API_KEY="${GLM_API_KEY}" \
sdp-protocol-e2e:latest
10 changes: 10 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@ bd close <id> # Complete work
bd sync # Sync with git
```

## Quality Gates

Before pushing code changes:

```bash
go build ./... # must succeed
go test ./... # must pass
go vet ./... # no issues
```

## Canonical Prompt Source

- Canonical prompts live in `prompts/skills/*/SKILL.md` and `prompts/agents/*.md`.
Expand Down
53 changes: 53 additions & 0 deletions ci/Dockerfile.protocol-e2e
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Protocol E2E test - full SDP protocol in isolated Docker environment
# Usage: docker build -f ci/Dockerfile.protocol-e2e -t sdp-protocol-e2e .
# docker run --rm -e GLM_API_KEY=... sdp-protocol-e2e

FROM golang:1.26-bookworm

RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
curl \
git \
jq \
libicu-dev \
libzstd-dev \
&& rm -rf /var/lib/apt/lists/*

# Install beads via release binary (v0.55.4 has sqlite; v0.56+ requires Dolt server)
ARG BEADS_VERSION=v0.55.4
ARG TARGETARCH
RUN ARCH=$(case $(uname -m) in aarch64|arm64) echo arm64;; x86_64|amd64) echo amd64;; *) echo amd64;; esac) && \
curl -fsSL -o /tmp/beads.tar.gz "https://github.com/steveyegge/beads/releases/download/${BEADS_VERSION}/beads_${BEADS_VERSION#v}_linux_${ARCH}.tar.gz" && \
tar -xzf /tmp/beads.tar.gz -C /usr/local/bin && rm /tmp/beads.tar.gz
ENV PATH="/usr/local/bin:/go/bin:$PATH"

# Install opencode CLI (for LLM integration phase)
# Use official install script - go package is archived
RUN curl -fsSL https://opencode.ai/install | bash || true

WORKDIR /workspace
# Repo COPY'd at build time
COPY . .

# Build SDP protocol binaries (evidence, guard, orchestrate, ci-loop, eval)
RUN go build -o /usr/local/bin/sdp-evidence ./cmd/sdp-evidence && \
go build -o /usr/local/bin/sdp-guard ./cmd/sdp-guard && \
go build -o /usr/local/bin/sdp-orchestrate ./cmd/sdp-orchestrate && \
go build -o /usr/local/bin/sdp-ci-loop ./cmd/sdp-ci-loop && \
go build -o /usr/local/bin/sdp-eval ./cmd/sdp-eval

# Build sdp CLI from sdp-plugin
RUN cd sdp-plugin && go build -o /usr/local/bin/sdp ./cmd/sdp

# Git config (needed for sdp-guard, orchestrate)
# When sdp is a submodule, .git is a file; re-init for E2E so git commands work
RUN rm -f .git 2>/dev/null; git init && git add -A && git commit -m "e2e" 2>/dev/null || true
RUN git config --global user.email "e2e@test" && \
git config --global user.name "E2E Test"

# Init beads in workspace (best-effort; repo .beads may exist)
RUN bd init 2>/dev/null || true
RUN bd sync 2>/dev/null || true

# GLM_API_KEY passed at runtime via -e (not baked into image)
CMD ["bash", "ci/protocol-e2e-test.sh"]
2 changes: 2 additions & 0 deletions ci/protocol-e2e-fixtures/beads-sdp-mapping-e2e.jsonl
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{"sdp_id":"00-999-01","beads_id":"sdp_dev-e2e01","updated_at":"2026-02-24T00:00:00.000Z"}
{"sdp_id":"00-999-02","beads_id":"sdp_dev-e2e01","updated_at":"2026-02-24T00:00:00.000Z"}
29 changes: 29 additions & 0 deletions ci/protocol-e2e-fixtures/docs/workstreams/backlog/00-999-01.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
ws_id: 00-999-01
feature_id: F999
status: backlog
priority: P3
size: XS
depends_on: []
---

# 00-999-01: E2E Hello (Protocol E2E Test)

Feature: F999 (sdp_dev-e2e01)

## Goal

Create `internal/e2e/hello.go` with a function `Hello() string` that returns `"hello"`. Used only for protocol E2E testing.

## Scope Files

- `internal/e2e/hello.go` — new: Hello function

## Acceptance Criteria

- [ ] `internal/e2e/hello.go` exists with `func Hello() string`
- [ ] `Hello()` returns `"hello"`

## Out of Scope

- Production use; this is E2E-only.
29 changes: 29 additions & 0 deletions ci/protocol-e2e-fixtures/docs/workstreams/backlog/00-999-02.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
ws_id: 00-999-02
feature_id: F999
status: backlog
priority: P3
size: XS
depends_on: ["00-999-01"]
---

# 00-999-02: E2E Hello Test (Protocol E2E Test)

Feature: F999 (sdp_dev-e2e01)

## Goal

Create `internal/e2e/hello_test.go` that tests `Hello()` returns `"hello"`. Used only for protocol E2E testing.

## Scope Files

- `internal/e2e/hello_test.go` — new: test for Hello

## Acceptance Criteria

- [ ] `internal/e2e/hello_test.go` exists with TestHello
- [ ] `go test ./internal/e2e/...` passes

## Out of Scope

- Production use; this is E2E-only.
4 changes: 4 additions & 0 deletions ci/protocol-e2e-fixtures/invalid-evidence.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"intent": {"issue_id": "test"},
"plan": {}
}
77 changes: 77 additions & 0 deletions ci/protocol-e2e-fixtures/valid-evidence.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
{
"intent": {
"issue_id": "sdp_dev-abc",
"trigger": "user",
"acceptance": [],
"risk_class": "low"
},
"plan": {
"workstreams": [],
"ordering_rationale": ""
},
"execution": {
"claimed_issue_ids": [],
"branch": "main",
"changed_files": []
},
"verification": {
"tests": [],
"lint": [],
"contracts": [],
"coverage": {"value": 80, "threshold": 80}
},
"review": {
"self_review": [],
"adversarial_review": []
},
"risk_notes": {
"residual_risks": [],
"out_of_scope": []
},
"boundary": {
"declared": {
"allowed_path_prefixes": [],
"control_path_prefixes": [],
"forbidden_path_prefixes": [],
"role": "",
"lane": ""
},
"observed": {
"touched_paths": [],
"out_of_boundary_paths": []
},
"compliance": {"ok": true, "reason": ""}
},
"provenance": {
"run_id": "run-1",
"orchestrator": "test",
"runtime": "local",
"model": "test",
"gate_results": [],
"phase": "execute",
"role": "coder",
"captured_at": "2026-01-01T00:00:00Z",
"source_issue_id": "sdp_dev-abc",
"artifact_id": "art-1",
"contract_version": "artifact-provenance/v1",
"hash_algorithm": "sha256",
"sequence": 0,
"payload_digest": "",
"hash": "",
"hash_prev": "",
"prompt_hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"context_sources": [
{
"type": "workstream_spec",
"path": "docs/workstreams/backlog/00-026-01.md",
"hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
}
]
},
"trace": {
"beads_ids": [],
"branch": "main",
"commits": [],
"pr_url": "https://github.com/org/repo/pull/1"
}
}
Loading
Loading