-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathMakefile
More file actions
271 lines (236 loc) · 12 KB
/
Copy pathMakefile
File metadata and controls
271 lines (236 loc) · 12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
BINARY := observer
PKG := github.com/marmutapp/superbased-observer
CMD := ./cmd/observer
GO ?= go
GOFLAGS ?=
BUILD_DIR := bin
COVER_OUT := coverage.txt
WEB_DIR := web
WEB_DIST := $(WEB_DIR)/dist
WEB_EMBED_DIST := internal/intelligence/dashboard/webapp/dist
.PHONY: all build test test-race test-invariant lint fmt vet tidy clean run cover \
build-observer build-antigravity-bridge \
web-install web-dev web-build web-clean \
plugins-build verify-plugins-build \
taxonomy-build verify-taxonomy-build verify-taxonomy-ts \
taxonomy-migration-build verify-taxonomy-migration \
assistant-migration-build verify-assistant-migration \
reasoning-migration-build verify-reasoning-migration
# Targets whose INPUTS are private-only paths (cmd/observer-org*,
# cmd/observer-edge, web2/, deploy/, docs/, website/, tools/toolcountgen)
# live in Makefile.private, which is excluded from the public snapshot
# via PRIVATE_ONLY_FILES in scripts/release.sh. `-include` (leading dash)
# tolerates its absence, so the public tree's `make build` builds exactly
# what README.md documents: bin/observer + the antigravity bridge.
# Private tree behaviour is unchanged.
PRIVATE_BUILD_TARGETS :=
-include Makefile.private
# `-include` fails SILENTLY, so a private-tree accident (rename, bad
# merge) would quietly stop `make build` producing bin/observer-org.
# CLAUDE.md is in PRIVATE_ONLY_PATHS and is physically removed from the
# public staging worktree, so this guard can only fire here.
ifeq ($(wildcard Makefile.private),)
ifneq ($(wildcard CLAUDE.md),)
$(error Makefile.private is missing on the private tree — restore it; \
the Enterprise build targets live there)
endif
endif
all: fmt vet lint test build
build: build-observer build-antigravity-bridge $(PRIVATE_BUILD_TARGETS)
build-observer:
@mkdir -p $(BUILD_DIR)
$(GO) build $(GOFLAGS) -o $(BUILD_DIR)/$(BINARY) $(CMD)
# Cross-compile the Antigravity Windows-side gRPC bridge. Used by
# observer-on-WSL2 to reach Antigravity's local language_server,
# which binds to Windows-side 127.0.0.1 and isn't reachable from
# inside a WSL distro under default networking. The bridge is a
# tiny Go binary (~8 MB) that runs Windows-side under powershell.exe,
# does process discovery + the gRPC call, and returns Markdown via
# stdout. Skipped silently on non-Linux build hosts where it'd
# never be invoked.
build-antigravity-bridge:
@mkdir -p $(BUILD_DIR)
GOOS=windows GOARCH=amd64 $(GO) build $(GOFLAGS) -o $(BUILD_DIR)/antigravity-bridge.exe ./cmd/antigravity-bridge
run: build
$(BUILD_DIR)/$(BINARY)
test:
$(GO) test $(GOFLAGS) ./...
# -timeout 40m matches ci.yml's test step. Without it the local run
# inherits go test's 10m per-binary default, and cmd/observer already
# measures 593s under -race on a developer box (2026-07-26) — ~7s of
# headroom, so a busy machine fails RED with `panic: test timed out`
# and nothing actually broken. The release checklist calls for a full
# race suite, which is exactly when that false failure would land.
test-race:
$(GO) test $(GOFLAGS) -race -timeout 40m ./...
# Single-user-local invariant net: seeds a fixed corpus, drives the
# dashboard's headline endpoints, and diffs the canonicalised JSON
# against goldens captured before the org-mode (Teams) code landed. A
# non-empty diff means an additive change leaked into a solo-local
# response — the one thing the Teams feature must never do. Regenerate
# the goldens intentionally with `go test ./tests/invariant -update`.
test-invariant:
$(GO) test $(GOFLAGS) ./tests/invariant/...
cover:
$(GO) test $(GOFLAGS) -race -coverprofile=$(COVER_OUT) -covermode=atomic ./...
$(GO) tool cover -func=$(COVER_OUT) | tail -1
# golangci-lint is deliberately NOT a `go tool` dependency: it pins its
# own Go version and must be built with the tree's Go (CI uses
# install-mode: goinstall for exactly that reason — see ci.yml). Resolve
# it from PATH first, then $(GOPATH)/bin, which is where `go install`
# puts it and which is not on PATH in every shell.
#
# A missing linter FAILS. It used to `exit 0`, which made every local
# `make lint` a green that meant "I didn't look" — the binary lives in
# $(GOPATH)/bin here and was never on PATH, so the guard fired every
# time and no local lint has ever actually run. CI was unaffected (it
# calls golangci-lint-action, not this target).
GOLANGCI_LINT ?= $(shell command -v golangci-lint 2>/dev/null || echo $(shell $(GO) env GOPATH)/bin/golangci-lint)
lint:
@test -x "$(GOLANGCI_LINT)" || { echo "golangci-lint not found at '$(GOLANGCI_LINT)' — install it (https://golangci-lint.run/, install-mode goinstall) or pass GOLANGCI_LINT=/path/to/golangci-lint"; exit 1; }
$(GOLANGCI_LINT) run ./...
fmt:
$(GO) tool gofumpt -w .
vet:
$(GO) vet ./...
tidy:
$(GO) mod tidy
clean:
rm -rf $(BUILD_DIR) $(COVER_OUT)
# ---------------------------------------------------------------
# Web (redesigned React/Vite dashboard, mounted at /v2/).
#
# `make build` stays pure-Go and does NOT require Node. The built
# artifacts at $(WEB_EMBED_DIST) are committed; regenerate them
# via `make web-build` whenever you touch web/ sources, before
# committing.
# ---------------------------------------------------------------
web-install:
cd $(WEB_DIR) && npm ci
web-dev:
cd $(WEB_DIR) && npm run dev
web-build:
cd $(WEB_DIR) && npm ci --silent && npm run build
@rm -rf $(WEB_EMBED_DIST)
@mkdir -p $(WEB_EMBED_DIST)
@cp -R $(WEB_DIST)/. $(WEB_EMBED_DIST)/
@echo "web: rebuilt $(WEB_EMBED_DIST) from $(WEB_DIST)"
web-clean:
rm -rf $(WEB_DIST) $(WEB_DIR)/node_modules
# ---------------------------------------------------------------
# In-tool plugin manifests (plugins/). plugins/plugingen RUNS the real
# `observer init` registrars — internal/mcp's Registrar and
# internal/hook's Registry — against a throwaway sandbox HOME and
# transposes exactly what they wrote into each surface's own packaging
# format: a Claude Code plugin + marketplace catalog, and the static
# Cursor one-click MCP install deeplink. Run after any change to those
# registrars (a new hook event, a changed MCP argument) or after a
# version stamp, so plugin wiring can never fork from init wiring —
# see docs/plans/adapter-plugins-distribution-plan-2026-07-31.md §3.
# ---------------------------------------------------------------
plugins-build:
$(GO) run ./plugins/plugingen
# Drift gate for the plugin manifests: copies plugins/ into a scratch
# dir, regenerates THERE and diffs against the committed files. Fails if
# a registrar moved without a matching `make plugins-build` + commit.
# Never mutates the working tree. Mirrors verify-track-build's
# build-into-temp pattern.
verify-plugins-build:
@scripts/verify-plugins-build.sh
# ---------------------------------------------------------------
# Dashboard action taxonomy (web/src/lib/actiontax.gen.*). web/taxgen
# mirrors internal/tooltax — the one owner of the cross-adapter tool/MCP
# taxonomy — into the shape web/src/lib/actions.ts reads: the canonical
# category list, the action-type → {category, label} registry, and the
# MCP name-parse rules (actiontax.gen.json), the ActionCategory literal
# union (actiontax.gen.ts), and the parity vectors the TypeScript gate
# runs (actiontax.vectors.gen.json). Run after any change to the tooltax
# action-type registry, categories or MCP constants, so the dashboard can
# never fork its own taxonomy again — see
# docs/plans/tool-taxonomy-standardization-plan-2026-07-31.md §1/§7.
# ---------------------------------------------------------------
taxonomy-build:
$(GO) run ./web/taxgen
# Drift gate for the generated taxonomy: regenerates into a scratch dir
# and byte-diffs each artifact against the committed one. Fails if
# tooltax moved without a matching `make taxonomy-build` + commit. Never
# mutates the working tree. Mirrors verify-plugins-build's
# build-into-temp pattern.
verify-taxonomy-build:
@scripts/verify-taxonomy-build.sh
# Cross-language parity gate: compiles the REAL web/src/lib/actions.ts
# (esbuild, from web/node_modules) and runs it against the generated
# vectors, whose expectations come from tooltax.MCPIdentity. Separate
# target from verify-taxonomy-build because it needs node + web deps,
# while the drift gate needs only Go. Both run in ci.yml's
# taxonomy-build-drift job.
verify-taxonomy-ts:
@scripts/verify-taxonomy-ts.sh
# ---------------------------------------------------------------
# Historical-data repair for the same taxonomy (internal/db/migrations/
# 077_tooltax_action_type_backfill.sql). internal/db/taxbackfillgen
# transposes the internal/tooltax table into one
# `UPDATE actions SET action_type = ... WHERE action_type = 'unknown'`
# per (tool, action type), so the rows already on disk get the categories
# their adapters only started emitting in WP-T3 — the plan's §3
# requirement that the repair SQL be SOURCED FROM the table rather than
# transcribed by hand.
# ---------------------------------------------------------------
taxonomy-migration-build:
$(GO) run ./internal/db/taxbackfillgen
# Drift gate for the generated migration: regenerates into a scratch dir
# and byte-diffs against the committed file. Fails on a hand-edit, or on
# a tooltax row that moved without a matching
# `make taxonomy-migration-build` + commit. Never mutates the working
# tree. Mirrors verify-taxonomy-build's build-into-temp pattern.
verify-taxonomy-migration:
@scripts/verify-taxonomy-migration.sh
# ---------------------------------------------------------------
# Historical-data repair for the assistant-text action-type relabel
# (internal/db/migrations/078_assistant_text_action_type_relabel.sql).
# internal/db/asstbackfillgen transposes the `<tool>.assistant_text`
# emit-site inventory into one
# `UPDATE actions SET action_type = 'assistant_message'
# WHERE tool = ... AND action_type = 'task_complete' AND raw_tool_name
# IN (...)` per tool, so the rows already on disk get the type the
# adapters emit after the WP-T6/B2a sweep.
#
# SIBLING of taxonomy-migration-build, deliberately not folded into it:
# 077 is sourced from internal/tooltax and is unknown-only (it can only
# move rows OUT of the unknown bucket), while 078 rewrites rows an
# adapter already classified. Regenerating 077 must never absorb 078's
# rewrite, so the generators, artifacts and gates stay separate.
# ---------------------------------------------------------------
assistant-migration-build:
$(GO) run ./internal/db/asstbackfillgen
# Drift gate for the generated relabel migration: regenerates into a
# scratch dir and byte-diffs against the committed file. Fails on a
# hand-edit, or on an emit site that moved without a matching
# `make assistant-migration-build` + commit. Never mutates the working
# tree. Mirrors verify-taxonomy-migration's build-into-temp pattern.
verify-assistant-migration:
@scripts/verify-assistant-migration.sh
# ---------------------------------------------------------------
# Historical-data repair for the B3 reasoning convergence
# (internal/db/migrations/079_reasoning_row_convergence.sql).
# internal/db/reasoninggen transposes the retired codex reasoning emit
# site's PLACEHOLDER shapes — `(reasoning)` and
# `(encrypted reasoning, N bytes)` — into a tool-scoped DELETE preceded
# by the retention.go dependency protocol, plus the cursor
# `cursor.assistant_response` pair rewrite that 078's `.assistant_text`
# scoping could not reach.
#
# SIBLING of assistant-migration-build, deliberately not folded into it:
# 078 REWRITES rows, 079 DELETES them. A delete is a strictly more
# dangerous mode and gets its own generator, its own artifact and its own
# gate, so one regeneration mistake can never turn a relabel into a
# deletion.
reasoning-migration-build:
$(GO) run ./internal/db/reasoninggen
# Drift gate for the generated convergence migration: regenerates into a
# scratch dir and byte-diffs against the committed file. Fails on a
# hand-edit, or on a producer shape / dependency table that moved without
# a matching `make reasoning-migration-build` + commit. Never mutates the
# working tree.
verify-reasoning-migration:
@scripts/verify-reasoning-migration.sh