chore: import upstream snapshot with attribution
govulncheck / govulncheck (push) Waiting to run
Harness (E2E) / Harnesses (mock LLM) (push) Waiting to run
Harness (E2E) / Provider harnesses (live LLM conformance) (push) Waiting to run
Lint / golangci-lint (push) Waiting to run
Run Tests / Unit Tests (push) Waiting to run
Run Tests / Etcd Integration Tests (push) Waiting to run
govulncheck / govulncheck (push) Waiting to run
Harness (E2E) / Harnesses (mock LLM) (push) Waiting to run
Harness (E2E) / Provider harnesses (live LLM conformance) (push) Waiting to run
Lint / golangci-lint (push) Waiting to run
Run Tests / Unit Tests (push) Waiting to run
Run Tests / Etcd Integration Tests (push) Waiting to run
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
name: govulncheck
|
||||
|
||||
# Deterministic vulnerability gate: runs govulncheck (reachability-aware CVE
|
||||
# scanner) on every push/PR. Fails on any reachable vulnerability EXCEPT the
|
||||
# explicit ALLOWLIST of known-unfixable ones, so a new vuln breaks the build
|
||||
# while tracked, no-upstream-fix ones don't. This is the gate the loop's
|
||||
# `security` role sits on top of — the role audits; this blocks known CVEs.
|
||||
#
|
||||
# Make this a required status check on the default branch to enforce it.
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["**"]
|
||||
pull_request:
|
||||
branches: ["**"]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
govulncheck:
|
||||
name: govulncheck
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: "1.25"
|
||||
check-latest: true
|
||||
- name: Install govulncheck
|
||||
run: go install golang.org/x/vuln/cmd/govulncheck@latest
|
||||
- name: Scan
|
||||
env:
|
||||
# Reachable vulnerabilities with NO upstream fix, accepted for now and
|
||||
# tracked for remediation. Remove an ID the moment its fix lands.
|
||||
# GO-2026-5004 github.com/jackc/pgx/v4 -> pgx v5 migration (#4556)
|
||||
# GO-2026-4518 github.com/jackc/pgproto3/v2 -> pgx v5 migration (#4556)
|
||||
ALLOWLIST: "GO-2026-5004 GO-2026-4518"
|
||||
run: |
|
||||
out=$(mktemp)
|
||||
govulncheck ./... >"$out" 2>&1 && code=0 || code=$?
|
||||
cat "$out"
|
||||
if [ "$code" -eq 0 ]; then
|
||||
echo "govulncheck: no reachable vulnerabilities."
|
||||
exit 0
|
||||
fi
|
||||
if [ "$code" -ne 3 ]; then
|
||||
echo "::error::govulncheck failed to run (exit $code)."
|
||||
exit 1
|
||||
fi
|
||||
found=$(grep -oE 'Vulnerability #[0-9]+: GO-[0-9]{4}-[0-9]+' "$out" | grep -oE 'GO-[0-9]{4}-[0-9]+' | sort -u)
|
||||
unexpected=""
|
||||
for id in $found; do
|
||||
case " $ALLOWLIST " in
|
||||
*" $id "*) ;;
|
||||
*) unexpected="$unexpected $id" ;;
|
||||
esac
|
||||
done
|
||||
if [ -n "$unexpected" ]; then
|
||||
echo "::error::Unexpected reachable vulnerabilities:$unexpected"
|
||||
echo "If a fix exists, bump the dependency/toolchain. If genuinely unfixable, add the ID to ALLOWLIST with a tracking issue."
|
||||
exit 1
|
||||
fi
|
||||
echo "govulncheck: only allow-listed (known-unfixable) vulnerabilities present:$found"
|
||||
echo "OK."
|
||||
@@ -0,0 +1,116 @@
|
||||
name: Harness (E2E)
|
||||
|
||||
# Runs the end-to-end harnesses for agents, services, flows, and provider
|
||||
# conformance. The default job uses deterministic mock LLMs and needs no
|
||||
# secrets. A second job runs the same harnesses against the live provider set and
|
||||
# skips providers whose secrets are absent, so scheduled conformance
|
||||
# remains safe in no-key forks while still failing configured providers that drift.
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["**"]
|
||||
pull_request:
|
||||
branches: ["**"]
|
||||
schedule:
|
||||
- cron: "17 * * * *" # hourly, so real-model conformance keeps pace with the dev/loop velocity
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
providers:
|
||||
description: "Comma-separated providers for live conformance (default: all supported)"
|
||||
required: false
|
||||
default: "anthropic,openai,gemini,groq,minimax,mistral,together,atlascloud"
|
||||
harnesses:
|
||||
description: "Comma-separated harnesses for live conformance"
|
||||
required: false
|
||||
default: "agent,universe,agent-flow,plan-delegate,a2a-stream-fallback"
|
||||
require_configured:
|
||||
description: "Fail selected live providers that do not have repository secrets"
|
||||
required: false
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
jobs:
|
||||
harness:
|
||||
name: Harnesses (mock LLM)
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: stable
|
||||
cache: true
|
||||
- name: Build
|
||||
run: go build ./...
|
||||
- name: 0→1 and 0→hero developer-flow harness
|
||||
run: make harness
|
||||
|
||||
harness-live:
|
||||
name: Provider harnesses (live LLM conformance)
|
||||
runs-on: ubuntu-latest
|
||||
# Only on the hourly schedule or a manual run — never automatically on
|
||||
# every push/PR, so changes don't quietly burn API credits. Trigger it
|
||||
# by hand (Actions → Harness → Run workflow) when changing the agent,
|
||||
# flow, or AI internals and you want a real-model check.
|
||||
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: stable
|
||||
cache: true
|
||||
- name: Provider conformance against live models
|
||||
env:
|
||||
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
||||
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
||||
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
|
||||
GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
|
||||
MINIMAX_API_KEY: ${{ secrets.MINIMAX_API_KEY }}
|
||||
MISTRAL_API_KEY: ${{ secrets.MISTRAL_API_KEY }}
|
||||
TOGETHER_API_KEY: ${{ secrets.TOGETHER_API_KEY }}
|
||||
ATLASCLOUD_API_KEY: ${{ secrets.ATLASCLOUD_API_KEY }}
|
||||
# Atlas Cloud's default chat model was failing the agent/tool-use
|
||||
# conformance harnesses; run it against a stronger tool-use model.
|
||||
# Override with an Actions variable ATLASCLOUD_MODEL if the exact
|
||||
# catalog id differs (Atlas uses org/model ids).
|
||||
ATLASCLOUD_MODEL: ${{ vars.ATLASCLOUD_MODEL || 'minimaxai/minimax-m3' }}
|
||||
run: |
|
||||
PROVIDERS="${{ github.event.inputs.providers || 'anthropic,openai,gemini,groq,minimax,mistral,together,atlascloud' }}"
|
||||
HARNESSES="${{ github.event.inputs.harnesses || 'agent,universe,agent-flow,plan-delegate,a2a-stream-fallback' }}"
|
||||
REQUIRE_CONFIGURED="${{ github.event.inputs.require_configured || 'false' }}"
|
||||
|
||||
args=(
|
||||
-providers "$PROVIDERS"
|
||||
-harnesses "$HARNESSES"
|
||||
-summary-json provider-conformance-summary.json
|
||||
-summary-markdown provider-conformance-summary.md
|
||||
-capabilities-markdown provider-capabilities.md
|
||||
)
|
||||
if [ "$REQUIRE_CONFIGURED" = "true" ]; then
|
||||
args+=( -require-configured )
|
||||
fi
|
||||
|
||||
go run ./internal/harness/provider-conformance "${args[@]}"
|
||||
- name: Publish provider conformance summary
|
||||
if: always()
|
||||
run: |
|
||||
if [ -f provider-conformance-summary.md ]; then
|
||||
cat provider-conformance-summary.md >> "$GITHUB_STEP_SUMMARY"
|
||||
fi
|
||||
if [ -f provider-capabilities.md ]; then
|
||||
{
|
||||
echo
|
||||
echo "## Registered provider capabilities"
|
||||
echo
|
||||
cat provider-capabilities.md
|
||||
} >> "$GITHUB_STEP_SUMMARY"
|
||||
fi
|
||||
- name: Upload provider conformance summary
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: provider-conformance
|
||||
path: |
|
||||
provider-conformance-summary.json
|
||||
provider-conformance-summary.md
|
||||
provider-capabilities.md
|
||||
if-no-files-found: ignore
|
||||
@@ -0,0 +1,30 @@
|
||||
name: Lint
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- "**"
|
||||
pull_request:
|
||||
types:
|
||||
- opened
|
||||
- reopened
|
||||
- synchronize
|
||||
branches:
|
||||
- "**"
|
||||
jobs:
|
||||
golangci:
|
||||
name: golangci-lint
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: "1.25"
|
||||
check-latest: true
|
||||
cache: true
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@v8
|
||||
with:
|
||||
version: v2.5.0
|
||||
@@ -0,0 +1,63 @@
|
||||
name: "Loop: Builder"
|
||||
|
||||
# Generated by `micro loop init`. A dispatch role of the autonomous loop: on a
|
||||
# cadence it opens a fresh tracking issue and posts the instruction in
|
||||
# .github/loop/prompts/builder.md to the agent (@codex).
|
||||
#
|
||||
# The workflow is the MECHANISM; that prompt file is the editable POLICY —
|
||||
# change what this role does by editing the prompt, not this YAML. A FRESH
|
||||
# issue per run is deliberate: agents derive the PR branch name from the
|
||||
# triggering issue, so reusing one tracker collapses every run onto one branch.
|
||||
#
|
||||
# Gated on CODEX_TRIGGER_TOKEN: the agent ignores @mentions from the
|
||||
# github-actions bot, so dispatch posts as a real user (a PAT). No token → no-op.
|
||||
|
||||
on:
|
||||
workflow_dispatch: {}
|
||||
# PAUSED 2026-07-12: automatic schedule disabled while the team does focused
|
||||
# 1:1 fixes. Still runnable on demand via workflow_dispatch. Re-enable by
|
||||
# uncommenting the schedule below.
|
||||
# schedule:
|
||||
# - cron: "29 * * * *"
|
||||
|
||||
permissions:
|
||||
issues: write
|
||||
|
||||
concurrency:
|
||||
group: loop-builder
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
dispatch:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4 # needed to read the prompt file
|
||||
- name: Dispatch builder
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.CODEX_TRIGGER_TOKEN || github.token }}
|
||||
HAS_TOKEN: ${{ secrets.CODEX_TRIGGER_TOKEN != '' }}
|
||||
REPO: ${{ github.repository }}
|
||||
RUN_NUMBER: ${{ github.run_number }}
|
||||
run: |
|
||||
if [ "$HAS_TOKEN" != "true" ]; then
|
||||
echo "CODEX_TRIGGER_TOKEN is not set — skipping (the agent ignores bot @mentions)."
|
||||
exit 0
|
||||
fi
|
||||
PROMPT=".github/loop/prompts/builder.md"
|
||||
if [ ! -f "$PROMPT" ]; then
|
||||
echo "missing $PROMPT — run 'micro loop init'." >&2
|
||||
exit 1
|
||||
fi
|
||||
ISSUE_URL=$(gh issue create --repo "$REPO" \
|
||||
--title "Loop: build increment #$RUN_NUMBER" \
|
||||
--body "Autonomous builder pass. Direction: .github/loop/NORTH_STAR.md; queue: .github/loop/PRIORITIES.md.")
|
||||
ISSUE_NUM="${ISSUE_URL##*/}"
|
||||
echo "Opened issue #$ISSUE_NUM — dispatching builder."
|
||||
# The prompt file is the policy; strip its editorial <!-- --> header and
|
||||
# substitute the tracking issue number (__ISSUE__) at runtime.
|
||||
{
|
||||
echo "@codex"
|
||||
echo
|
||||
sed -e '/<!--/,/-->/d' -e "s/__ISSUE__/$ISSUE_NUM/g" "$PROMPT"
|
||||
} > "$RUNNER_TEMP/loop-body.md"
|
||||
gh issue comment "$ISSUE_NUM" --repo "$REPO" --body-file "$RUNNER_TEMP/loop-body.md"
|
||||
@@ -0,0 +1,63 @@
|
||||
name: "Loop: Coherence"
|
||||
|
||||
# Generated by `micro loop init`. A dispatch role of the autonomous loop: on a
|
||||
# cadence it opens a fresh tracking issue and posts the instruction in
|
||||
# .github/loop/prompts/coherence.md to the agent (@codex).
|
||||
#
|
||||
# The workflow is the MECHANISM; that prompt file is the editable POLICY —
|
||||
# change what this role does by editing the prompt, not this YAML. A FRESH
|
||||
# issue per run is deliberate: agents derive the PR branch name from the
|
||||
# triggering issue, so reusing one tracker collapses every run onto one branch.
|
||||
#
|
||||
# Gated on CODEX_TRIGGER_TOKEN: the agent ignores @mentions from the
|
||||
# github-actions bot, so dispatch posts as a real user (a PAT). No token → no-op.
|
||||
|
||||
on:
|
||||
workflow_dispatch: {}
|
||||
# PAUSED 2026-07-12: automatic schedule disabled while the team does focused
|
||||
# 1:1 fixes. Still runnable on demand via workflow_dispatch. Re-enable by
|
||||
# uncommenting the schedule below.
|
||||
# schedule:
|
||||
# - cron: "0 7 * * *"
|
||||
|
||||
permissions:
|
||||
issues: write
|
||||
|
||||
concurrency:
|
||||
group: loop-coherence
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
dispatch:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4 # needed to read the prompt file
|
||||
- name: Dispatch coherence
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.CODEX_TRIGGER_TOKEN || github.token }}
|
||||
HAS_TOKEN: ${{ secrets.CODEX_TRIGGER_TOKEN != '' }}
|
||||
REPO: ${{ github.repository }}
|
||||
RUN_NUMBER: ${{ github.run_number }}
|
||||
run: |
|
||||
if [ "$HAS_TOKEN" != "true" ]; then
|
||||
echo "CODEX_TRIGGER_TOKEN is not set — skipping (the agent ignores bot @mentions)."
|
||||
exit 0
|
||||
fi
|
||||
PROMPT=".github/loop/prompts/coherence.md"
|
||||
if [ ! -f "$PROMPT" ]; then
|
||||
echo "missing $PROMPT — run 'micro loop init'." >&2
|
||||
exit 1
|
||||
fi
|
||||
ISSUE_URL=$(gh issue create --repo "$REPO" \
|
||||
--title "Loop: coherence review #$RUN_NUMBER" \
|
||||
--body "Autonomous coherence pass. Direction: .github/loop/NORTH_STAR.md; queue: .github/loop/PRIORITIES.md.")
|
||||
ISSUE_NUM="${ISSUE_URL##*/}"
|
||||
echo "Opened issue #$ISSUE_NUM — dispatching coherence."
|
||||
# The prompt file is the policy; strip its editorial <!-- --> header and
|
||||
# substitute the tracking issue number (__ISSUE__) at runtime.
|
||||
{
|
||||
echo "@codex"
|
||||
echo
|
||||
sed -e '/<!--/,/-->/d' -e "s/__ISSUE__/$ISSUE_NUM/g" "$PROMPT"
|
||||
} > "$RUNNER_TEMP/loop-body.md"
|
||||
gh issue comment "$ISSUE_NUM" --repo "$REPO" --body-file "$RUNNER_TEMP/loop-body.md"
|
||||
@@ -0,0 +1,63 @@
|
||||
name: "Loop: Planner"
|
||||
|
||||
# Generated by `micro loop init`. A dispatch role of the autonomous loop: on a
|
||||
# cadence it opens a fresh tracking issue and posts the instruction in
|
||||
# .github/loop/prompts/planner.md to the agent (@codex).
|
||||
#
|
||||
# The workflow is the MECHANISM; that prompt file is the editable POLICY —
|
||||
# change what this role does by editing the prompt, not this YAML. A FRESH
|
||||
# issue per run is deliberate: agents derive the PR branch name from the
|
||||
# triggering issue, so reusing one tracker collapses every run onto one branch.
|
||||
#
|
||||
# Gated on CODEX_TRIGGER_TOKEN: the agent ignores @mentions from the
|
||||
# github-actions bot, so dispatch posts as a real user (a PAT). No token → no-op.
|
||||
|
||||
on:
|
||||
workflow_dispatch: {}
|
||||
# PAUSED 2026-07-12: automatic schedule disabled while the team does focused
|
||||
# 1:1 fixes. Still runnable on demand via workflow_dispatch. Re-enable by
|
||||
# uncommenting the schedule below.
|
||||
# schedule:
|
||||
# - cron: "59 * * * *"
|
||||
|
||||
permissions:
|
||||
issues: write
|
||||
|
||||
concurrency:
|
||||
group: loop-planner
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
dispatch:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4 # needed to read the prompt file
|
||||
- name: Dispatch planner
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.CODEX_TRIGGER_TOKEN || github.token }}
|
||||
HAS_TOKEN: ${{ secrets.CODEX_TRIGGER_TOKEN != '' }}
|
||||
REPO: ${{ github.repository }}
|
||||
RUN_NUMBER: ${{ github.run_number }}
|
||||
run: |
|
||||
if [ "$HAS_TOKEN" != "true" ]; then
|
||||
echo "CODEX_TRIGGER_TOKEN is not set — skipping (the agent ignores bot @mentions)."
|
||||
exit 0
|
||||
fi
|
||||
PROMPT=".github/loop/prompts/planner.md"
|
||||
if [ ! -f "$PROMPT" ]; then
|
||||
echo "missing $PROMPT — run 'micro loop init'." >&2
|
||||
exit 1
|
||||
fi
|
||||
ISSUE_URL=$(gh issue create --repo "$REPO" \
|
||||
--title "Loop: planning review #$RUN_NUMBER" \
|
||||
--body "Autonomous planner pass. Direction: .github/loop/NORTH_STAR.md; queue: .github/loop/PRIORITIES.md.")
|
||||
ISSUE_NUM="${ISSUE_URL##*/}"
|
||||
echo "Opened issue #$ISSUE_NUM — dispatching planner."
|
||||
# The prompt file is the policy; strip its editorial <!-- --> header and
|
||||
# substitute the tracking issue number (__ISSUE__) at runtime.
|
||||
{
|
||||
echo "@codex"
|
||||
echo
|
||||
sed -e '/<!--/,/-->/d' -e "s/__ISSUE__/$ISSUE_NUM/g" "$PROMPT"
|
||||
} > "$RUNNER_TEMP/loop-body.md"
|
||||
gh issue comment "$ISSUE_NUM" --repo "$REPO" --body-file "$RUNNER_TEMP/loop-body.md"
|
||||
@@ -0,0 +1,100 @@
|
||||
name: "Loop: Release"
|
||||
|
||||
# Generated by `micro loop init`. Cuts the next tag when the default branch has
|
||||
# new commits since the latest one, and pushes it with a PAT (CODEX_TRIGGER_TOKEN)
|
||||
# so any tag-triggered release workflow fires. The bump reflects what shipped,
|
||||
# read from the CHANGELOG [Unreleased] section: new features (Added/Changed) cut
|
||||
# a MINOR; fixes/docs only cut a PATCH; breaking changes are skipped so a MAJOR
|
||||
# stays a human decision.
|
||||
#
|
||||
# The tag MUST be pushed with a PAT, not the default GITHUB_TOKEN: a tag pushed
|
||||
# by GITHUB_TOKEN does not trigger other workflows (Actions blocks that recursion).
|
||||
|
||||
on:
|
||||
workflow_dispatch: {}
|
||||
# PAUSED 2026-07-12: automatic nightly release disabled while the team does
|
||||
# focused 1:1 fixes. Cut a release on demand via workflow_dispatch. Re-enable
|
||||
# by uncommenting the schedule below.
|
||||
# schedule:
|
||||
# - cron: "0 23 * * *"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: loop-release
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0 # need full history + all tags
|
||||
# Do NOT persist the default GITHUB_TOKEN as a git credential: it would
|
||||
# be sent on the PAT push below and override it, so the tag push would
|
||||
# authenticate as github-actions[bot] and 403. Letting the PAT in the
|
||||
# push URL be the only credential is the whole point.
|
||||
persist-credentials: false
|
||||
- name: Cut the next patch tag if there are new commits
|
||||
env:
|
||||
RELEASE_TOKEN: ${{ secrets.CODEX_TRIGGER_TOKEN }}
|
||||
REPO: ${{ github.repository }}
|
||||
run: |
|
||||
if [ -z "$RELEASE_TOKEN" ]; then
|
||||
echo "CODEX_TRIGGER_TOKEN is not set — skipping."
|
||||
exit 0
|
||||
fi
|
||||
git fetch --tags --force
|
||||
|
||||
LATEST=$(git tag --list 'v*.*.*' --sort=-v:refname | head -1)
|
||||
if [ -z "$LATEST" ]; then
|
||||
echo "no vMAJOR.MINOR.PATCH tag found — aborting so nothing weird gets tagged."
|
||||
exit 1
|
||||
fi
|
||||
echo "latest tag: $LATEST"
|
||||
|
||||
COUNT=$(git rev-list --count "$LATEST"..HEAD)
|
||||
echo "commits since $LATEST: $COUNT"
|
||||
if [ "$COUNT" -eq 0 ]; then
|
||||
echo "no new commits since $LATEST — no release."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
ver="${LATEST#v}"
|
||||
major="${ver%%.*}"
|
||||
rest="${ver#*.}"
|
||||
minor="${rest%%.*}"
|
||||
patch="${rest#*.}"
|
||||
case "$major.$minor.$patch" in
|
||||
[0-9]*.[0-9]*.[0-9]*) ;;
|
||||
*) echo "unexpected tag shape: $LATEST" ; exit 1 ;;
|
||||
esac
|
||||
|
||||
# Choose the bump from what actually shipped, read from the CHANGELOG
|
||||
# [Unreleased] section (kept current by the coherence role):
|
||||
# new features (### Added / ### Changed) -> MINOR
|
||||
# fixes/docs only -> PATCH
|
||||
# breaking (### Removed / "(breaking)") -> skip; a major is a human call
|
||||
UNRELEASED=""
|
||||
if [ -f CHANGELOG.md ]; then
|
||||
UNRELEASED=$(awk '/^## \[Unreleased\]/{f=1; next} /^## \[/{f=0} f' CHANGELOG.md)
|
||||
fi
|
||||
if printf '%s\n' "$UNRELEASED" | grep -qiE '^### Removed|^### Changed \(breaking\)|BREAKING'; then
|
||||
echo "CHANGELOG [Unreleased] contains breaking changes — a major release is a human decision. Skipping."
|
||||
exit 0
|
||||
elif printf '%s\n' "$UNRELEASED" | grep -qE '^### (Added|Changed)'; then
|
||||
NEXT="v${major}.$((minor + 1)).0"
|
||||
KIND="minor (new features)"
|
||||
else
|
||||
NEXT="v${major}.${minor}.$((patch + 1))"
|
||||
KIND="patch (fixes/docs only)"
|
||||
fi
|
||||
echo "cutting: $NEXT — $KIND ($COUNT commits since $LATEST)"
|
||||
|
||||
git config user.name "loop release bot"
|
||||
git config user.email "noreply@users.noreply.github.com"
|
||||
git tag -a "$NEXT" -m "Release $NEXT — automated $KIND ($COUNT commits since $LATEST)"
|
||||
git push "https://x-access-token:${RELEASE_TOKEN}@github.com/${REPO}.git" "$NEXT"
|
||||
echo "Pushed $NEXT."
|
||||
@@ -0,0 +1,63 @@
|
||||
name: "Loop: Security"
|
||||
|
||||
# Generated by `micro loop init`. A dispatch role of the autonomous loop: on a
|
||||
# cadence it opens a fresh tracking issue and posts the instruction in
|
||||
# .github/loop/prompts/security.md to the agent (@codex).
|
||||
#
|
||||
# The workflow is the MECHANISM; that prompt file is the editable POLICY —
|
||||
# change what this role does by editing the prompt, not this YAML. A FRESH
|
||||
# issue per run is deliberate: agents derive the PR branch name from the
|
||||
# triggering issue, so reusing one tracker collapses every run onto one branch.
|
||||
#
|
||||
# Gated on CODEX_TRIGGER_TOKEN: the agent ignores @mentions from the
|
||||
# github-actions bot, so dispatch posts as a real user (a PAT). No token → no-op.
|
||||
|
||||
on:
|
||||
workflow_dispatch: {}
|
||||
# PAUSED 2026-07-12: automatic schedule disabled while the team does focused
|
||||
# 1:1 fixes. Still runnable on demand via workflow_dispatch. Re-enable by
|
||||
# uncommenting the schedule below.
|
||||
# schedule:
|
||||
# - cron: "0 6 * * 1"
|
||||
|
||||
permissions:
|
||||
issues: write
|
||||
|
||||
concurrency:
|
||||
group: loop-security
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
dispatch:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4 # needed to read the prompt file
|
||||
- name: Dispatch security
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.CODEX_TRIGGER_TOKEN || github.token }}
|
||||
HAS_TOKEN: ${{ secrets.CODEX_TRIGGER_TOKEN != '' }}
|
||||
REPO: ${{ github.repository }}
|
||||
RUN_NUMBER: ${{ github.run_number }}
|
||||
run: |
|
||||
if [ "$HAS_TOKEN" != "true" ]; then
|
||||
echo "CODEX_TRIGGER_TOKEN is not set — skipping (the agent ignores bot @mentions)."
|
||||
exit 0
|
||||
fi
|
||||
PROMPT=".github/loop/prompts/security.md"
|
||||
if [ ! -f "$PROMPT" ]; then
|
||||
echo "missing $PROMPT — run 'micro loop init'." >&2
|
||||
exit 1
|
||||
fi
|
||||
ISSUE_URL=$(gh issue create --repo "$REPO" \
|
||||
--title "Loop: security review #$RUN_NUMBER" \
|
||||
--body "Autonomous security pass. Direction: .github/loop/NORTH_STAR.md; queue: .github/loop/PRIORITIES.md.")
|
||||
ISSUE_NUM="${ISSUE_URL##*/}"
|
||||
echo "Opened issue #$ISSUE_NUM — dispatching security."
|
||||
# The prompt file is the policy; strip its editorial <!-- --> header and
|
||||
# substitute the tracking issue number (__ISSUE__) at runtime.
|
||||
{
|
||||
echo "@codex"
|
||||
echo
|
||||
sed -e '/<!--/,/-->/d' -e "s/__ISSUE__/$ISSUE_NUM/g" "$PROMPT"
|
||||
} > "$RUNNER_TEMP/loop-body.md"
|
||||
gh issue comment "$ISSUE_NUM" --repo "$REPO" --body-file "$RUNNER_TEMP/loop-body.md"
|
||||
@@ -0,0 +1,61 @@
|
||||
name: "Loop: Triage"
|
||||
|
||||
# Generated by `micro loop init`. The feedback path of the evaluator: when a CI
|
||||
# workflow (Harness (E2E), Lint, Run Tests) fails on a non-PR run, dispatch the agent
|
||||
# (@codex) with the instruction in .github/loop/prompts/triage.md
|
||||
# to root-cause the failure and file scoped fix issues back into the queue — so
|
||||
# failures become fixes with no human in the middle. Gated on CODEX_TRIGGER_TOKEN.
|
||||
|
||||
on:
|
||||
workflow_dispatch: {}
|
||||
# PAUSED 2026-07-12: automatic CI-failure dispatch disabled while the team
|
||||
# does focused 1:1 fixes, so failures don't auto-spawn agent tasks. Re-enable
|
||||
# by uncommenting the workflow_run trigger below.
|
||||
# workflow_run:
|
||||
# workflows: ["Harness (E2E)", "Lint", "Run Tests", "govulncheck"]
|
||||
# types: [completed]
|
||||
|
||||
permissions:
|
||||
issues: write
|
||||
|
||||
concurrency:
|
||||
group: loop-triage
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
triage:
|
||||
# Only real failures on branch pushes/schedules — not PR-run failures, which
|
||||
# the PR author already sees.
|
||||
if: ${{ github.event.workflow_run.conclusion == 'failure' && github.event.workflow_run.event != 'pull_request' }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4 # needed to read the prompt file
|
||||
- name: Dispatch triage
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.CODEX_TRIGGER_TOKEN || github.token }}
|
||||
HAS_TOKEN: ${{ secrets.CODEX_TRIGGER_TOKEN != '' }}
|
||||
REPO: ${{ github.repository }}
|
||||
RUN_ID: ${{ github.event.workflow_run.id }}
|
||||
RUN_URL: ${{ github.event.workflow_run.html_url }}
|
||||
WORKFLOW_NAME: ${{ github.event.workflow_run.name }}
|
||||
run: |
|
||||
if [ "$HAS_TOKEN" != "true" ]; then
|
||||
echo "CODEX_TRIGGER_TOKEN is not set — skipping."
|
||||
exit 0
|
||||
fi
|
||||
PROMPT=".github/loop/prompts/triage.md"
|
||||
if [ ! -f "$PROMPT" ]; then
|
||||
echo "missing $PROMPT — run 'micro loop init'." >&2
|
||||
exit 1
|
||||
fi
|
||||
ISSUE_URL=$(gh issue create --repo "$REPO" \
|
||||
--title "Loop: triage failed run $RUN_ID ($WORKFLOW_NAME)" \
|
||||
--body "The '$WORKFLOW_NAME' workflow failed on a non-PR run: $RUN_URL")
|
||||
ISSUE_NUM="${ISSUE_URL##*/}"
|
||||
echo "Opened issue #$ISSUE_NUM — dispatching triage."
|
||||
{
|
||||
echo "@codex"
|
||||
echo
|
||||
sed -e '/<!--/,/-->/d' -e "s/__ISSUE__/$ISSUE_NUM/g" -e "s#__RUNURL__#$RUN_URL#g" "$PROMPT"
|
||||
} > "$RUNNER_TEMP/loop-body.md"
|
||||
gh issue comment "$ISSUE_NUM" --repo "$REPO" --body-file "$RUNNER_TEMP/loop-body.md"
|
||||
@@ -0,0 +1,51 @@
|
||||
name: goreleaser
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*.*.*'
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
id-token: write
|
||||
packages: write
|
||||
attestations: write
|
||||
jobs:
|
||||
goreleaser:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
-
|
||||
name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: stable
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
-
|
||||
name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
-
|
||||
name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
-
|
||||
name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@v7
|
||||
with:
|
||||
distribution: goreleaser
|
||||
version: '~> v2'
|
||||
args: release --clean
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -0,0 +1,75 @@
|
||||
name: Run Tests
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- "**"
|
||||
pull_request:
|
||||
types:
|
||||
- opened
|
||||
- reopened
|
||||
- synchronize
|
||||
branches:
|
||||
- "**"
|
||||
jobs:
|
||||
unittests:
|
||||
name: Unit Tests
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: "1.25"
|
||||
check-latest: true
|
||||
cache: true
|
||||
- name: Get dependencies
|
||||
run: |
|
||||
go install github.com/kyoh86/richgo@latest
|
||||
go get -v -t -d ./...
|
||||
- name: Run tests
|
||||
id: tests
|
||||
run: richgo test -v -race -cover ./...
|
||||
env:
|
||||
IN_TRAVIS_CI: yes
|
||||
RICHGO_FORCE_COLOR: 1
|
||||
|
||||
etcd-integration:
|
||||
name: Etcd Integration Tests
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
services:
|
||||
etcd:
|
||||
image: quay.io/coreos/etcd:v3.5.2
|
||||
env:
|
||||
ETCD_LISTEN_CLIENT_URLS: http://0.0.0.0:2379
|
||||
ETCD_ADVERTISE_CLIENT_URLS: http://0.0.0.0:2379
|
||||
ports:
|
||||
- 2379:2379
|
||||
options: >-
|
||||
--health-cmd "etcdctl endpoint health"
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: "1.25"
|
||||
check-latest: true
|
||||
cache: true
|
||||
- name: Get dependencies
|
||||
run: |
|
||||
go install github.com/kyoh86/richgo@latest
|
||||
go get -v -t -d ./...
|
||||
- name: Wait for etcd
|
||||
run: |
|
||||
timeout 30 bash -c 'until curl -s http://localhost:2379/health; do sleep 1; done'
|
||||
- name: Run etcd integration tests
|
||||
run: richgo test -v -race ./registry/etcd/...
|
||||
env:
|
||||
ETCD_ADDRESS: localhost:2379
|
||||
IN_TRAVIS_CI: yes
|
||||
RICHGO_FORCE_COLOR: 1
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
# Sample workflow for building and deploying a Jekyll site to GitHub Pages
|
||||
name: Deploy Jekyll with GitHub Pages dependencies preinstalled
|
||||
|
||||
on:
|
||||
# Runs on pushes targeting the default branch
|
||||
push:
|
||||
branches: ["master"]
|
||||
|
||||
# Allows you to run this workflow manually from the Actions tab
|
||||
workflow_dispatch:
|
||||
|
||||
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
|
||||
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
|
||||
concurrency:
|
||||
group: "pages"
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
# Build job
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Setup Pages
|
||||
uses: actions/configure-pages@v5
|
||||
- name: Build with Jekyll
|
||||
uses: actions/jekyll-build-pages@v1
|
||||
with:
|
||||
source: ./internal/website
|
||||
destination: ./_site
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
|
||||
# Deployment job
|
||||
deploy:
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
steps:
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
||||
Reference in New Issue
Block a user