Skip to content
Merged
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
2 changes: 1 addition & 1 deletion .clinerules/tech.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

## Primary

- **Go 1.26+**, statically linked (`CGO_ENABLED=0`). The `ctx`
- **Go 1.27+**, statically linked (`CGO_ENABLED=0`). The `ctx`
binary is the entire deliverable for the core; everything else
ships as embedded bytes inside it.
- **Cobra** for the CLI command surface.
Expand Down
2 changes: 1 addition & 1 deletion .context/steering/tech.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ priority: 10

## Primary

- **Go 1.26+**, statically linked (`CGO_ENABLED=0`). The `ctx`
- **Go 1.27+**, statically linked (`CGO_ENABLED=0`). The `ctx`
binary is the entire deliverable for the core; everything else
ships as embedded bytes inside it.
- **Cobra** for the CLI command surface.
Expand Down
2 changes: 1 addition & 1 deletion .cursor/rules/tech.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ alwaysApply: true

## Primary

- **Go 1.26+**, statically linked (`CGO_ENABLED=0`). The `ctx`
- **Go 1.27+**, statically linked (`CGO_ENABLED=0`). The `ctx`
binary is the entire deliverable for the core; everything else
ships as embedded bytes inside it.
- **Cobra** for the CLI command surface.
Expand Down
12 changes: 9 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v7
with:
go-version: '1.26'
go-version: '1.27'

- name: Build
run: CGO_ENABLED=0 go build ./...
Expand Down Expand Up @@ -59,14 +59,20 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v7
with:
go-version: '1.26'
go-version: '1.27'

- name: Run golangci-lint
uses: golangci/golangci-lint-action@v9
with:
version: v2.11.4
version: v2.13.2
args: --timeout=5m

- name: Check Go toolchain version sync
run: make check-go-version

- name: Check steering outputs freshness
run: make check-steering

typecheck-opencode-plugin:
name: Typecheck OpenCode plugin
runs-on: ubuntu-latest
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v7
with:
go-version: '1.26'
go-version: '1.27'

- name: Run tests
run: CGO_ENABLED=0 go test ./...
Expand Down Expand Up @@ -54,7 +54,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v7
with:
go-version: '1.26'
go-version: '1.27'

- name: Test
run: CGO_ENABLED=0 go test -v ./...
Expand Down
2 changes: 1 addition & 1 deletion .kiro/steering/tech.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ mode: always

## Primary

- **Go 1.26+**, statically linked (`CGO_ENABLED=0`). The `ctx`
- **Go 1.27+**, statically linked (`CGO_ENABLED=0`). The `ctx`
binary is the entire deliverable for the core; everything else
ships as embedded bytes inside it.
- **Cobra** for the CLI command surface.
Expand Down
27 changes: 21 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
clean all release build-all help \
test-coverage smoke site site-guard site-feed site-serve site-serve-lan site-setup audit check plugin-reload \
journal journal-serve journal-serve-lan gpg-fix gpg-test register-mcp reinstall check-tools \
sync-version check-version-sync sync-why check-why sync-copilot-skills check-copilot-skills sync-codex-skills check-codex-skills codex-plugin-install sync-opencode-skills check-opencode-skills sync-pi-skills check-pi-skills sync-steering check-steering gemini-search \
sync-version check-version-sync check-go-version sync-why check-why sync-copilot-skills check-copilot-skills sync-codex-skills check-codex-skills codex-plugin-install sync-opencode-skills check-opencode-skills sync-steering check-steering gemini-search \
gitnexus-version gitnexus-update gitnexus-index gitnexus-mcp strip-gitnexus install-ctxctl reinstall-ctxctl

# Default binary name and output
Expand Down Expand Up @@ -175,6 +175,8 @@ audit:
fi
@echo "==> Checking version sync..."
@$(MAKE) --no-print-directory check-version-sync
@echo "==> Checking Go toolchain version sync..."
@$(MAKE) --no-print-directory check-go-version
@echo "==> Checking why docs freshness..."
@$(MAKE) --no-print-directory check-why
@echo "==> Checking Copilot skills freshness..."
Expand Down Expand Up @@ -398,6 +400,10 @@ check-version-sync:
fi; \
echo "Version sync OK ($$V)."

## check-go-version: Verify every Go toolchain pin agrees with the go.mod directive
check-go-version:
@./hack/check-go-version.sh

## sync-copilot-skills: Sync Copilot CLI skills from canonical ctx skills
sync-copilot-skills:
@./hack/sync-copilot-skills.sh
Expand Down Expand Up @@ -432,14 +438,23 @@ sync-steering:
@CGO_ENABLED=0 go run ./cmd/ctx steering sync --all

## check-steering: Verify tracked steering outputs match .context/steering source
# Snapshot-then-regenerate (same shape as check-copilot-skills): compares
# the working-tree outputs against a fresh sync, not against HEAD, so an
# uncommitted-but-consistent source/output pair passes locally.
check-steering:
@CGO_ENABLED=0 go run ./cmd/ctx steering sync --all > /dev/null
@if ! git diff --quiet -- .cursor .clinerules .kiro/steering; then \
@TMPDIR=$$(mktemp -d) && \
mkdir -p "$$TMPDIR/before" "$$TMPDIR/after" && \
cp -r .cursor/rules .clinerules .kiro/steering "$$TMPDIR/before/" && \
CGO_ENABLED=0 go run ./cmd/ctx steering sync --all > /dev/null && \
cp -r .cursor/rules .clinerules .kiro/steering "$$TMPDIR/after/" && \
if ! diff -rq "$$TMPDIR/before" "$$TMPDIR/after" > /dev/null 2>&1; then \
echo "FAIL: steering outputs are stale — run 'make sync-steering' and commit"; \
git --no-pager diff --stat -- .cursor .clinerules .kiro/steering; \
diff -rq "$$TMPDIR/before" "$$TMPDIR/after" || true; \
rm -rf "$$TMPDIR"; \
exit 1; \
fi
@echo "Steering outputs are in sync."
fi; \
rm -rf "$$TMPDIR"; \
echo "Steering outputs are in sync."

## check-copilot-skills: Verify Copilot CLI skills match ctx source skills
check-copilot-skills:
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/ActiveMemory/ctx

go 1.26.3
go 1.27.1

require (
github.com/hashicorp/raft v1.8.0
Expand Down
2 changes: 1 addition & 1 deletion go.work
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
go 1.26.3
go 1.27.1

// ctx (the shipped user binary) and tools/ctxctl (maintainer-only)
// are separate modules. ctx never requires tools/ctxctl, so it can
Expand Down
10 changes: 10 additions & 0 deletions go.work.sum
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ github.com/circonus-labs/circonusllhist v0.1.3 h1:TJH+oke8D16535+jHExHj4nQvzlZrj
github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2 h1:aBangftG7EVZoUb69Os8IaYg++6uMOdKK83QtkkvJik=
github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2/go.mod h1:qwXFYgsP6T7XnJtbKlf1HP8AjxZZyzxMmc+Lq5GjlU4=
github.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0=
github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w=
github.com/davecgh/go-xdr v0.0.0-20161123171359-e6a2ba005892 h1:qg9VbHo1TlL0KDM0vYvBG9EY0X0Yku5WYIPoFWt8f6o=
github.com/davecgh/go-xdr v0.0.0-20161123171359-e6a2ba005892/go.mod h1:CTDl0pzVzE5DEzZhPfvhY/9sPFMQIxaJ9VAMs9AagrE=
github.com/envoyproxy/go-control-plane v0.14.0 h1:hbG2kr4RuFj222B6+7T83thSPqLjwBIfQawTkC++2HA=
Expand Down Expand Up @@ -74,6 +75,7 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU=
github.com/philhofer/fwd v1.1.2 h1:bnDivRJ1EWPjUIRXV5KfORO897HTbpFAQddBdE8t7Gw=
github.com/philhofer/fwd v1.1.2/go.mod h1:qkPdfjR2SIEbspLqpe1tO4n5yICnr2DY7mqEx2tUTP0=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e h1:aoZm08cpOy4WuID//EZDgcC4zIxODThtZNPirFr42+A=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo=
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8=
Expand All @@ -91,6 +93,8 @@ github.com/spiffe/go-spiffe/v2 v2.6.0/go.mod h1:gm2SeUoMZEtpnzPNs2Csc0D/gX33k1xI
github.com/spiffe/go-spiffe/v2 v2.7.0 h1:uXe1MflJoHw58wAUvxVlcM7WpKtijWG7I1UidcGh6g4=
github.com/spiffe/go-spiffe/v2 v2.7.0/go.mod h1:47Q0Q9/AqGha8QLHp+kxpH4Wca7X7EnOtlIJy3mxZ3U=
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/tinylib/msgp v1.1.8 h1:FCXC1xanKO4I8plpHGH2P7koL/RzZs12l/+r7vakfm0=
github.com/tinylib/msgp v1.1.8/go.mod h1:qkpG+2ldGg4xRFmx+jfTvZPxfGFhi64BcnL9vkCm/Tw=
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 h1:G3dpKMzFDjgEh2q1Z7zUUtKa8ViPtH+ocF0bE0g00O8=
Expand All @@ -109,6 +113,8 @@ golang.org/x/crypto v0.53.0 h1:QZ4Muo8THX6CizN2vPPd5fBGHyogrdK9fG4wLPFUsto=
golang.org/x/crypto v0.53.0/go.mod h1:DNLU434OwVakk9PzuwV8w62mAJpRJL3vsgcfp4Qnsio=
golang.org/x/crypto v0.55.0 h1:+KWHjbgOaAQ66dh/YlkZKHlz9ZUlq61AFirAR9ntP8M=
golang.org/x/crypto v0.55.0/go.mod h1:uq0V9dE/fzQuJtbnL+2EhWOE63vo164FY8xqEnV9xis=
golang.org/x/crypto v0.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M=
golang.org/x/crypto v0.57.0/go.mod h1:Fdz0i5U6CoizGwLda9DttjSk6qlZo25zYNtR+ycvuZA=
golang.org/x/mod v0.37.0 h1:vF1DjpVEshcIqoEaauuHebaLk1O1forxjxBaVn884JQ=
golang.org/x/mod v0.37.0/go.mod h1:m8S8VeM9r4dzDwjrKO0a1sZP3YjeMamRRlD+fmR2Q/0=
golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o=
Expand All @@ -125,12 +131,16 @@ golang.org/x/telemetry v0.0.0-20260625142307-59b4966ccb57 h1:nwGZBCt+FnXUrGsj5vj
golang.org/x/telemetry v0.0.0-20260625142307-59b4966ccb57/go.mod h1:3AWMyWHS+caVoiEXpiq6+tzKA40J4vQT3MYr80ZtQpc=
golang.org/x/telemetry v0.0.0-20260811182544-a038080d80e5 h1:ZUSxONxc981v7AW7QUg+I9WwZzSTTJ019ENBYr5pV/Q=
golang.org/x/telemetry v0.0.0-20260811182544-a038080d80e5/go.mod h1:LVehoXe41cL5SCVQilsV7Gg6BNG+Js6P9PhSbYTIUkQ=
golang.org/x/telemetry v0.0.0-20260908163034-4bcc4b2ee518 h1:F5BWKvW126NXR74uxkxuc1jQHhm/rwm/J3rSiFyuRs4=
golang.org/x/telemetry v0.0.0-20260908163034-4bcc4b2ee518/go.mod h1:i+ivNqjDnTF3WTElsdk5g9V5DTSBYgdNo7xTU9SDwYA=
golang.org/x/term v0.43.0 h1:S4RLU2sB31O/NCl+zFN9Aru9A/Cq2aqKpTZJ6B+DwT4=
golang.org/x/term v0.43.0/go.mod h1:lrhlHNdQJHO+1qVYiHfFKVuVioJIheAc3fBSMFYEIsk=
golang.org/x/term v0.44.0 h1:0rLvDRCtNj0gZkyIXhCyOb2OAzEhLVqc4B+hrsBhrmc=
golang.org/x/term v0.44.0/go.mod h1:7ze4MdzUzLXpSAoFP1H0bOI9aXDqveSvatT5vKcFh2Y=
golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0=
golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w=
golang.org/x/term v0.46.0 h1:3+OXuTbaKDgwk8jTi3aSLHRlmWqHEUDUtxnbFigO4YE=
golang.org/x/term v0.46.0/go.mod h1:+K02xbkittuwc0Am4abfA3Fc+XRGXkvBXNO88NCXPoc=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
Expand Down
96 changes: 96 additions & 0 deletions hack/check-go-version.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#!/usr/bin/env bash
# / ctx: https://ctx.ist
# ,'`./ do you remember?
# `.,'\
# \ Copyright 2026-present Context contributors.
# SPDX-License-Identifier: Apache-2.0


# check-go-version.sh — one Go version, many pins, zero drift.
#
# The `go` directive in the root go.mod is the single source of truth.
# Every other place the toolchain version is written down must agree
# with it, or a hurried bump ships a stale pin:
#
# exact (major.minor.patch must match go.mod):
# go.work
# tools/ctxctl/go.mod
# floor (major.minor must match go.mod):
# .github/workflows/*.yml every `go-version:` pin
# hack/tool-versions.txt the `go bin required <min>` row
# .context/steering/tech.md the "**Go X.Y+**" prose (tool-native
# copies are covered by `make check-steering`)
#
# Portable: bash 3.2 + BSD awk/grep (see specs/hack-script-portability.md).
#
# Exit code: number of mismatches (0 = clean).

set -euo pipefail

ROOT="$(cd "$(dirname "$0")/.." && pwd)"
cd "$ROOT"

issues=0

fail() {
echo "FAIL: $1"
issues=$((issues + 1))
}

# First `go <version>` directive in a go.mod / go.work file.
go_directive() {
awk '$1 == "go" { print $2; exit }' "$1"
}

FULL="$(go_directive go.mod)"
if [ -z "$FULL" ]; then
echo "FAIL: no 'go' directive in go.mod" >&2
exit 1
fi
MINOR="$(printf '%s\n' "$FULL" | awk -F. '{ print $1 "." $2 }')"

# --- exact pins -----------------------------------------------------------

for f in go.work tools/ctxctl/go.mod; do
got="$(go_directive "$f")"
if [ "$got" != "$FULL" ]; then
fail "$f: go $got != go.mod $FULL"
fi
done

# --- floor pins -----------------------------------------------------------

# Workflows: every go-version pin, quoted or bare.
found=0
for wf in .github/workflows/*.yml; do
while IFS= read -r line; do
found=$((found + 1))
got="$(printf '%s\n' "$line" | sed -e "s/.*go-version:[[:space:]]*//" -e "s/['\"]//g" -e 's/[[:space:]]*$//')"
if [ "$got" != "$MINOR" ]; then
fail "$wf: go-version '$got' != go.mod $MINOR"
fi
done < <(grep -E '^[[:space:]]*go-version:' "$wf" || true)
done
if [ "$found" -eq 0 ]; then
fail ".github/workflows: no go-version pins found (grep pattern drifted?)"
fi

# Tool manifest: the go row's minimum.
got="$(awk '$1 == "go" && $2 == "bin" { print $4; exit }' hack/tool-versions.txt)"
if [ "$got" != "$MINOR" ]; then
fail "hack/tool-versions.txt: go minimum '$got' != go.mod $MINOR"
fi

# Steering source prose: "**Go X.Y+**".
got="$(grep -o -E 'Go [0-9]+\.[0-9]+\+' .context/steering/tech.md | head -1 | sed -e 's/^Go //' -e 's/+$//')"
if [ "$got" != "$MINOR" ]; then
fail ".context/steering/tech.md: 'Go ${got:-?}+' != go.mod $MINOR"
fi

# --- verdict --------------------------------------------------------------

if [ "$issues" -gt 0 ]; then
echo "Go version drift: $issues mismatch(es) — go.mod says $FULL; align the sites above."
exit "$issues"
fi
echo "Go version sync OK ($FULL / floor $MINOR)."
2 changes: 1 addition & 1 deletion hack/check-tools.sh
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ with_timeout() {
fi
}

# First dotted-number token in a version banner ("go1.26.3",
# First dotted-number token in a version banner ("go1.27.1",
# "v24.18.0", "jq-1.7.1" all yield the bare number).
extract_version() {
grep -oE '[0-9]+(\.[0-9]+)+' | head -1
Expand Down
4 changes: 3 additions & 1 deletion hack/tool-versions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
# Version minimums live here so bumps are one-line diffs.

# Build / lint core — the check fails without these.
go bin required 1.26
# The go minimum must match the go.mod directive's major.minor;
# hack/check-go-version.sh (make check-go-version) enforces it.
go bin required 1.27
git bin required -
golangci-lint bin required -

Expand Down
2 changes: 1 addition & 1 deletion specs/check-tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ Three pieces:

| Manifest value | Semantics | Below | Above |
|----------------|-----------|-------|----------|
| `1.26` | minimum | `OUTDATED` | `OK` |
| `1.27` | minimum | `OUTDATED` | `OK` |
| `=0.0.51` | exact pin | `OUTDATED` | `DRIFT` |
| `-` | presence | — | — |

Expand Down
Loading
Loading