@veleads/gtm 0.4.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,58 @@ All notable changes to `@veleads/gtm`. Each entry is tagged: **no action**, **op
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ ## [0.7.0] - 2026-10-24
9
+ - **opt-in** `gtm stack up | down [--wipe] | status`: each project repo runs its own stack (Postgres +
10
+ hatchet-lite + gtm worker) on Docker, as compose project `gtm-<project_id>` with its own volumes. The
11
+ worker is the image `ghcr.io/veleads/gtm-worker:<version>` matching the pinned core; it applies
12
+ database migrations when it starts. Connection settings go to `~/.gtm/stacks/<project_id>.env`
13
+ (used by `gtm job`), provider keys to `~/.gtm/stacks/<project_id>.secrets.env`; nothing is written
14
+ into the repo. Ports are configurable (`GTM_PG_PORT`, `GTM_HATCHET_UI_PORT`, `GTM_HATCHET_GRPC_PORT`)
15
+ and bound to localhost only. Releases now also publish the worker image. The gtm-core development
16
+ stack (`pnpm stack:up` + `pnpm worker`) still works as a fallback for `gtm job`.
17
+ - **action** One database per project: each project repo runs its own stack (Postgres + Hatchet +
18
+ workers) and core holds no project state. Rows no longer carry `project_id`; unique keys are now
19
+ per database (`accounts` on `tam_id` + `domain`, `contacts` on `linkedin_url`, …). A new
20
+ single-row `project` table binds the database to one `project_id` on the first job, and workers
21
+ refuse jobs for any other project. The `account`, `contact`, `lead` and `signal` schemas drop
22
+ `project_id`; `project.yaml` and job payloads keep it. DB migration
23
+ `20261025000000_database_per_project` binds an existing single-project database automatically and
24
+ **refuses to run on a database that holds more than one project**: give each project its own
25
+ database (copy its rows, filtered by `project_id`) before upgrading. Point each project's
26
+ `DATABASE_URL` at its own database.
27
+
28
+ ## [0.6.0] - 2026-10-24
29
+ - **no action** Layered ICP: `context/icp.yaml` can have an optional `core.firmographics` that every
30
+ segment shares; segments then hold only what differs, and a segment field **replaces** the same core
31
+ field (lists are not combined). Segments may restrict `personas`. Existing ICPs are unchanged and
32
+ stay valid. A segment that resolves to no filters at all is rejected.
33
+ - **no action** `gtm icp` shows the ICP as jobs see it: core, each segment's final filters (marking
34
+ which fields the segment sets), personas and exclusions. `gtm job tam` uses the resolved filters.
35
+ - **no action** `01-icp` skill and `icp.md` / `icp.yaml` templates rewritten around the five layers
36
+ (core, segments, personas, signals, exclusions) with a hypothesis, evidence and success criteria per
37
+ segment; `research` now outputs core and segment candidates. AGENTS.md states the assumption: from
38
+ stage 2 on the ICP is approved (stage 1 ends with a decision, revising later is normal).
39
+ - **opt-in** `gtm job tam <campaign>` is available: builds the TAM through the workers (Hatchet) into
40
+ Postgres and prints the funnel (TAM → reachable → active), cost, run_id and a run-log row. Needs an
41
+ approved ICP and `config.yaml` → `tam: { source, max_accounts_per_segment }`; `mock-accounts`
42
+ generates fictional accounts to prove the pipeline locally. Re-runs update instead of duplicating;
43
+ suppression lowers "active". Local stack: `pnpm stack:up` + `pnpm worker` in gtm-core.
44
+
45
+ ## [0.5.0] - 2026-10-24
46
+ - **action** Research-first intake: new `research` skill writes `context/research.md` (sourced facts,
47
+ public customers as suppression candidates, competitors as exclusion candidates, triggers) before any
48
+ questions; `00-intake` drafts intake from it and asks only what research can't answer, with an
49
+ example per question. `validate` warns while `context/research.md` is missing.
50
+ - **action** GitHub-enforced approvals: when `owners.approver` is an `@handle`, ICP and copy sign-off is
51
+ the approver's APPROVED review on a PR. `gtm approve icp|copy … --pr <n>` verifies it on GitHub and
52
+ records `approved_via`; `gtm validate` requires it, and `--verify-github` (in the CI template)
53
+ re-checks the review and that the reviewed commit matches the pinned hash. `gtm sync` maintains a
54
+ CODEOWNERS block for the approver. Named approvers keep `--by`. Existing repos: copy
55
+ `.gtm/templates/repo/github/workflows/gtm.yml` to enable verification in CI.
56
+ - **opt-in** `gtm track` mirrors stages and gates into a tracker (`project.yaml` → `tracker.kind`:
57
+ `github` issues, or `none`, the default for existing repos). New `gtm github setup [--apply]` creates
58
+ labels and the approval ruleset. Guide: `.gtm/guides/github.md` (incl. an org-wide board).
59
+
8
60
  ## [0.4.0] - 2026-10-24
9
61
  - **no action** `gtm init . --name "<Name>"` sets up the current folder instead of creating a
10
62
  subfolder (slug from the folder name, e.g. `gtm-project-acme` → `acme`, or `--slug`). Built for a
package/README.md CHANGED
@@ -48,8 +48,10 @@ command writes**, and examples, without running it.
48
48
  | `new-campaign <slug>` | scaffold `campaigns/<slug>/` | that folder |
49
49
  | `validate [campaign]` | schemas, gates, cross-references, no lead data, core sync | nothing |
50
50
  | `status` | campaigns, stages, gates | nothing |
51
- | `approve icp --by "<name>"` | record ICP sign-off, pin its hash | `context/icp.yaml` |
52
- | `approve copy <campaign> --by "<name>"` | record copy sign-off, pin its hash | campaign `config.yaml` |
51
+ | `approve icp --pr <n>` / `--by "<name>"` | record ICP sign-off (GitHub PR review, or by name), pin its hash | `context/icp.yaml` |
52
+ | `approve copy <campaign> --pr <n>` / `--by "<name>"` | record copy sign-off the same way | campaign `config.yaml` |
53
+ | `track stage\|gate-open\|gate-done …` | mirror stages and gates as GitHub issues (or `none`) | tracker only |
54
+ | `github setup [--apply]` | labels + approval ruleset on the repo | GitHub settings |
53
55
  | `sync [--check]` | copy the core kit into `.gtm/` + `AGENTS.md` | `.gtm/`, `AGENTS.md` (nothing with `--check`) |
54
56
  | `migrate [--dry-run]` | move YAML files to the current schema versions | YAML files |
55
57
  | `upgrade [version]` | install a newer core, sync, migrate, validate, show changelog | deps, `.gtm/`, YAML |
@@ -57,9 +59,18 @@ command writes**, and examples, without running it.
57
59
 
58
60
  Exit codes: `0` success, `1` failure or validation errors.
59
61
 
62
+ ## GitHub mode
63
+
64
+ Set `project.yaml` owners to GitHub handles (`approver: "@maria"`). ICP and copy sign-off then **is**
65
+ the approver's PR review: `gtm sync` makes them the CODEOWNER of those files, `gtm approve … --pr <n>`
66
+ verifies the review on GitHub, and CI (`gtm validate --verify-github`) re-checks it against the exact
67
+ reviewed content. Stages and gates are mirrored as issues with `gtm track`. Approvers who aren't on
68
+ GitHub (or solo projects) use a plain name and `--by`. Details: `.gtm/guides/github.md`.
69
+
60
70
  ## For coding agents
61
71
 
62
72
  - Inside a project repo, **read `AGENTS.md` first** and follow it; then `PROJECT.md`.
73
+ - Intake starts with the `research` skill: research the business before asking anyone anything.
63
74
  - Read-only commands are always safe: `validate`, `status`, `sync --check`, `migrate --dry-run`,
64
75
  and any `--help`.
65
76
  - Never edit `AGENTS.md` or `.gtm/`. Never run `gtm approve` unless a named human explicitly approved