fullstackgtm 0.28.1 → 0.28.3
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 +38 -0
- package/CONTRIBUTING.md +92 -0
- package/README.md +1 -1
- package/docs/architecture.md +101 -0
- package/docs/roadmap-to-1.0.md +12 -2
- package/llms.txt +2 -0
- package/package.json +3 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,44 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
|
5
5
|
and the project adheres to [Semantic Versioning](https://semver.org/).
|
|
6
6
|
The path to 1.0 is planned in [docs/roadmap-to-1.0.md](./docs/roadmap-to-1.0.md).
|
|
7
7
|
|
|
8
|
+
## [0.28.3] — 2026-06-16
|
|
9
|
+
|
|
10
|
+
Fix broken links in the published mirror. CONTRIBUTING.md and CLAUDE.md
|
|
11
|
+
referenced `../../docs/open-core-boundary.md` — a monorepo-root path that
|
|
12
|
+
escapes the repo on the mirror (where the package is the repo root) and targets
|
|
13
|
+
a doc the mirror doesn't carry. Made those references self-contained (the
|
|
14
|
+
open-core model and release ritual are explained inline). A full sweep confirms
|
|
15
|
+
every relative link in the shipped docs now resolves within the package/mirror.
|
|
16
|
+
|
|
17
|
+
## [0.28.2] — 2026-06-16
|
|
18
|
+
|
|
19
|
+
Collaborator/co-maintainer onboarding (from a readiness review). No runtime
|
|
20
|
+
code changes; one dev-ergonomics fix.
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
- **Package-local `npm test` no longer silently passes with zero tests.** A
|
|
25
|
+
`pretest` guard fails with a pointer to run package tests from the monorepo
|
|
26
|
+
root (the tests live there; the package-local script is meaningful only on the
|
|
27
|
+
published mirror). Previously a maintainer could change code, run the package's
|
|
28
|
+
test command, see green, and ship a regression.
|
|
29
|
+
|
|
30
|
+
### Added
|
|
31
|
+
|
|
32
|
+
- **CONTRIBUTING.md at the package root** (the README link previously 404'd in
|
|
33
|
+
the source repo — it existed only in the mirror-staging dir). Covers dev setup,
|
|
34
|
+
the test-from-root rule, the open-core mirror topology, the release ritual, and
|
|
35
|
+
the access a co-maintainer needs to cut a release.
|
|
36
|
+
- **docs/architecture.md** — module map + snapshot → audit → plan → apply data
|
|
37
|
+
flow + "where do I add a rule / connector / operation".
|
|
38
|
+
- A package-scoped **CLAUDE.md** so an agent/maintainer isn't pointed at the
|
|
39
|
+
hosted app's Convex stack.
|
|
40
|
+
|
|
41
|
+
### Changed
|
|
42
|
+
|
|
43
|
+
- README benchmark line reconciled with RESULTS.md (1,088-run, six models);
|
|
44
|
+
roadmap-to-1.0 shipped-layers list extended through 0.28.
|
|
45
|
+
|
|
8
46
|
## [0.28.1] — 2026-06-16
|
|
9
47
|
|
|
10
48
|
Company-of-record correction: the legal entity is **Full Stack GTM LLC** and the
|
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Thanks for your interest in `fullstackgtm`! This covers both outside
|
|
4
|
+
contributors and co-maintainers.
|
|
5
|
+
|
|
6
|
+
## How this repository works (open-core mirror)
|
|
7
|
+
|
|
8
|
+
`fullstackgtm` is open-core. The development **source of truth** is a private
|
|
9
|
+
monorepo (the package lives at `packages/fullstackgtm`), alongside the hosted
|
|
10
|
+
Full Stack GTM LLC application. `scripts/sync-oss.sh` publishes a **one-way
|
|
11
|
+
mirror** to [github.com/fullstackgtm/core](https://github.com/fullstackgtm/core)
|
|
12
|
+
and to npm. The mirror has the package at its repo root, the tests in `tests/`
|
|
13
|
+
with rewritten import paths, and `dist/` committed (so `npm install
|
|
14
|
+
github:fullstackgtm/core` works without a build step).
|
|
15
|
+
|
|
16
|
+
- **Issues / PRs:** open them on the public mirror (`fullstackgtm/core`). A
|
|
17
|
+
maintainer applies accepted changes in the monorepo with credit
|
|
18
|
+
(`Co-authored-by`); they land in the next mirrored release.
|
|
19
|
+
- The open/closed boundary: client tools, the canonical model, rules, the
|
|
20
|
+
plan/apply contract, connectors, CLI, and MCP server are open; the hosted Full
|
|
21
|
+
Stack GTM application's server code is not. **Features never move from open to
|
|
22
|
+
closed**, and new work here must run standalone (no hosted deployment
|
|
23
|
+
required). (Maintainers: the full boundary policy lives in
|
|
24
|
+
`docs/open-core-boundary.md` in the development monorepo.)
|
|
25
|
+
|
|
26
|
+
## Architecture
|
|
27
|
+
|
|
28
|
+
Start with [docs/architecture.md](./docs/architecture.md) for the module map and
|
|
29
|
+
the snapshot → audit → plan → approve → apply data flow, then
|
|
30
|
+
[docs/api.md](./docs/api.md) for the 1.0 contract surface (canonical model, rule
|
|
31
|
+
interface, connector interface, governed write verbs, MCP tools).
|
|
32
|
+
|
|
33
|
+
## Development
|
|
34
|
+
|
|
35
|
+
The package is zero-runtime-dependency TypeScript. **In the monorepo**, it is
|
|
36
|
+
built and tested from the repo root after a single root `npm install` (it shares
|
|
37
|
+
the root's dev toolchain; it is not a separately-installed workspace):
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# from the monorepo root:
|
|
41
|
+
npm install # once
|
|
42
|
+
cd packages/fullstackgtm && npm run build # tsc → dist/ (cleans first)
|
|
43
|
+
node --experimental-strip-types --test tests/fullstackgtm*.test.ts # from the repo ROOT — tests live there
|
|
44
|
+
node packages/fullstackgtm/src/bin.ts doctor # run the CLI locally
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
> **Tests live at the monorepo root `tests/`, not in the package.** Running
|
|
48
|
+
> `npm test` *inside* `packages/fullstackgtm` deliberately fails with a pointer
|
|
49
|
+
> (a `pretest` guard) rather than silently passing with zero tests. On the
|
|
50
|
+
> published mirror, `tests/` is present and `npm test` works there.
|
|
51
|
+
|
|
52
|
+
**Node:** the published runtime supports Node ≥ 20 (`engines`), but the test
|
|
53
|
+
runner needs Node **≥ 22.6** for `--experimental-strip-types`. Develop on 22.6+.
|
|
54
|
+
|
|
55
|
+
Keep the core dependency-free — a new runtime dependency needs a very strong
|
|
56
|
+
reason (the MCP server's `@modelcontextprotocol/sdk`/`zod` are optional peers,
|
|
57
|
+
imported only by the MCP entrypoints).
|
|
58
|
+
|
|
59
|
+
## Safety invariants (do not weaken)
|
|
60
|
+
|
|
61
|
+
- Audits/suggests are read-only; nothing is written without explicit approval.
|
|
62
|
+
- `apply` writes only operations whose ids were approved; `requires_human_*`
|
|
63
|
+
placeholders are refused without a concrete `--value`.
|
|
64
|
+
- Approvals are HMAC-signed and re-verified at apply (integrity.ts) — a plan
|
|
65
|
+
edited after approval is refused.
|
|
66
|
+
- Irreversible ops (merge/archive) get a fresh-snapshot drift guard; archiving a
|
|
67
|
+
record that still shares an identity key with another is refused.
|
|
68
|
+
- Secrets are never accepted as argv flags — stdin or env only.
|
|
69
|
+
- Finding/operation ids stay stable hashes of rule + record.
|
|
70
|
+
|
|
71
|
+
When in doubt, add a test in `tests/fullstackgtm*.test.ts` (the suite doubles as
|
|
72
|
+
the spec) and run the security suite (`fullstackgtmSecurity.test.ts`).
|
|
73
|
+
|
|
74
|
+
## Releasing (maintainers)
|
|
75
|
+
|
|
76
|
+
The steps are below (deeper rationale lives in `docs/open-core-boundary.md` in
|
|
77
|
+
the development monorepo). From the monorepo:
|
|
78
|
+
|
|
79
|
+
1. Bump `packages/fullstackgtm/package.json` version + add a `CHANGELOG.md`
|
|
80
|
+
entry; merge to `main`.
|
|
81
|
+
2. `scripts/sync-oss.sh --push` (builds a fresh `dist/`, mirrors the package +
|
|
82
|
+
rewritten tests to `fullstackgtm/core`).
|
|
83
|
+
3. Re-check the mirror's `package.json` version, then tag `vX.Y.Z` on the mirror
|
|
84
|
+
and push the tag.
|
|
85
|
+
4. GitHub Actions (`release.yml`) publishes to npm via **OIDC trusted
|
|
86
|
+
publishing** — no tokens. It rebuilds from source and refuses to publish if
|
|
87
|
+
the committed `dist/` differs from a fresh build (supply-chain gate).
|
|
88
|
+
|
|
89
|
+
**Access a new co-maintainer needs to cut a release:** write access to
|
|
90
|
+
`github.com/fullstackgtm/core` (for `sync-oss.sh --push` and the tag push). No
|
|
91
|
+
npm token is required — publishing is OIDC-bound to the repo + `release.yml`.
|
|
92
|
+
Cut one supervised patch release end-to-end before taking over release duty.
|
package/README.md
CHANGED
|
@@ -219,7 +219,7 @@ fullstackgtm diff --before old.json --after new.json --fail-on-new-findings
|
|
|
219
219
|
- `--demo` (with `--seed`) generates a realistic mid-market CRM with injected real-world failure modes — departed owners, unlinked deals, orphan accounts, stale pipeline — so agents and CI can exercise the full snapshot → audit → apply pipeline with zero credentials.
|
|
220
220
|
- Exit codes: `0` success, `1` error, `2` findings at/above `--fail-on`.
|
|
221
221
|
|
|
222
|
-
"Built for agents" is measured, not asserted: a 1,
|
|
222
|
+
"Built for agents" is measured, not asserted: a 1,088-run benchmark (17 scenarios = 14 synthetic + 3 seeded from an anonymized real portal, × 3 tool-surface arms × 4 trials, across six models from three vendors, deterministic graders over final CRM state, τ-bench-style pass^k) shows the gated CLI surface beating raw CRM-API access on completion-under-policy for every model tested — and the tool-surface effect is monotonic and vendor-independent. Full matrix and methodology: [the leaderboard](./evals/crm/leaderboard/RESULTS.md).
|
|
223
223
|
|
|
224
224
|
The design is **deterministic apply, governed suggest**: the parts that touch your CRM — the audit rules, the plan/apply contract, compare-and-set, the survivor/merge logic — are deterministic and replayable; the parts that read free text (`call parse`/`score`, `market classify`) are LLM-powered but bounded, with every quoted span mechanically verified against the source before it can drive a writeback. Nondeterministic suggestion, deterministic governance.
|
|
225
225
|
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
A one-page map for someone about to change this code. The companion
|
|
4
|
+
[api.md](./api.md) documents the contract surface by capability; this doc
|
|
5
|
+
documents the *layout* and *data flow*.
|
|
6
|
+
|
|
7
|
+
## The one idea
|
|
8
|
+
|
|
9
|
+
**Deterministic apply, governed suggest.** Everything that touches a CRM is
|
|
10
|
+
deterministic, replayable, and human-approved; anything that reads free text
|
|
11
|
+
(call transcripts, competitor pages) is LLM-powered but bounded — its quoted
|
|
12
|
+
evidence is mechanically verified against the source before it can drive a
|
|
13
|
+
write. Hold this line when adding features.
|
|
14
|
+
|
|
15
|
+
## Core data flow
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
provider ──fetchSnapshot()──► CanonicalGtmSnapshot
|
|
19
|
+
│
|
|
20
|
+
▼
|
|
21
|
+
audit (rules.ts × audit.ts)
|
|
22
|
+
│
|
|
23
|
+
▼
|
|
24
|
+
PatchPlan (dry-run; typed operations)
|
|
25
|
+
│ suggest.ts fills requires_human_* values
|
|
26
|
+
▼
|
|
27
|
+
plans approve (planStore.ts + integrity.ts: HMAC-signed)
|
|
28
|
+
│
|
|
29
|
+
▼
|
|
30
|
+
applyPatchPlan (connector.ts): for each APPROVED op —
|
|
31
|
+
compare-and-set vs live value, precondition + guard recheck,
|
|
32
|
+
irreversible-op drift guard → connector.applyOperation()
|
|
33
|
+
│
|
|
34
|
+
▼
|
|
35
|
+
PatchPlanRun (the audit record; auditLog.ts exports it)
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Module map (`src/`)
|
|
39
|
+
|
|
40
|
+
**Contracts & model**
|
|
41
|
+
- `types.ts` — the canonical data model and every load-bearing contract
|
|
42
|
+
(`CanonicalGtmSnapshot`, `PatchPlan`/`PatchOperation`, `GtmConnector`,
|
|
43
|
+
`GtmAuditRule`). Read this first; each field is documented with *why* it exists.
|
|
44
|
+
- `index.ts` — the public API manifest (one re-export block per module).
|
|
45
|
+
|
|
46
|
+
**Audit → plan → apply (the governed loop)**
|
|
47
|
+
- `rules.ts` — the 12 built-in deterministic audit rules + `GtmAuditRule` (the
|
|
48
|
+
public extension point) + stable-id hashing.
|
|
49
|
+
- `audit.ts` — runs rules over a snapshot into a `PatchPlan`.
|
|
50
|
+
- `suggest.ts` — derives concrete values for `requires_human_*` placeholders from
|
|
51
|
+
snapshot evidence, with confidence + reasons.
|
|
52
|
+
- `planStore.ts` — durable plan lifecycle (save / approve / record runs), 0600.
|
|
53
|
+
- `integrity.ts` — HMAC-signs approvals (per-install key) and verifies at apply.
|
|
54
|
+
- `connector.ts` — `applyPatchPlan`: the safety contract (approval filter,
|
|
55
|
+
placeholder refusal, CAS, precondition/guard recheck, irreversible-op drift
|
|
56
|
+
guard). Provider-agnostic.
|
|
57
|
+
- `auditLog.ts` — hash-chained, signed export of every apply run.
|
|
58
|
+
|
|
59
|
+
**Governed write verbs (each builds a plan; never writes directly)**
|
|
60
|
+
- `bulkUpdate.ts`, `dedupe.ts`, `reassign.ts` — filtered/duplicate/ownership
|
|
61
|
+
plan builders. `merge.ts` — snapshot diff/merge + entity resolution.
|
|
62
|
+
- `resolve.ts` — the create-gate (exists / ambiguous / safe_to_create).
|
|
63
|
+
|
|
64
|
+
**Connectors** (`connectors/`)
|
|
65
|
+
- `hubspot.ts`, `salesforce.ts`, `stripe.ts` + their `*Auth.ts` OAuth/device
|
|
66
|
+
flows. A connector implements `GtmConnector` (`fetchSnapshot`, optional
|
|
67
|
+
`applyOperation`/`readField`/`fetchChanges`). `mappings.ts` holds field maps.
|
|
68
|
+
|
|
69
|
+
**Free-text layers (LLM-bounded)**
|
|
70
|
+
- `calls.ts` + `llm.ts` — transcript parse/score; LLM insights pass a verbatim
|
|
71
|
+
span gate before becoming evidence/writes.
|
|
72
|
+
- `market*.ts` (`market.ts`, `marketClassify.ts`, `marketAxes.ts`,
|
|
73
|
+
`marketOverlay.ts`, `marketScale.ts`, `marketReport.ts`) — the competitive
|
|
74
|
+
market-map layer; classifications are verbatim-verified against captures.
|
|
75
|
+
- `enrich.ts` + `enrichApollo.ts` — third-party data enrichment (fill-blanks).
|
|
76
|
+
|
|
77
|
+
**Surfaces & infra**
|
|
78
|
+
- `cli.ts` — one async function per command, flat dispatch in `runCli`;
|
|
79
|
+
orchestration only (all logic lives in the modules above). `bin.ts` is the
|
|
80
|
+
entrypoint. `mcp.ts`/`mcp-bin.ts` — the MCP server (optional peers).
|
|
81
|
+
- `credentials.ts` — credential store (0600 file, or OS keychain via
|
|
82
|
+
`keychain.ts` when `FSGTM_KEYCHAIN=1`); broker pairing client.
|
|
83
|
+
- `schedule.ts` — local cron provider (read/plan-side allowlist; never
|
|
84
|
+
auto-approves). `report.ts`/`format.ts` — rendering. `config.ts`,
|
|
85
|
+
`profiles.ts`, `sampleData.ts`.
|
|
86
|
+
|
|
87
|
+
## Where do I add…
|
|
88
|
+
|
|
89
|
+
- **a new audit rule** → implement `GtmAuditRule`, register it; see api.md
|
|
90
|
+
"Write a custom rule". Add a `tests/fullstackgtm*.test.ts`.
|
|
91
|
+
- **a new connector** → implement `GtmConnector`; see api.md "Use a connector
|
|
92
|
+
programmatically".
|
|
93
|
+
- **a new operation type** → extend `PatchOperationType` in types.ts, handle it
|
|
94
|
+
in `connector.ts` apply + each connector's `applyOperation`, and decide its
|
|
95
|
+
safety class (does it need CAS / a drift guard / approval signing coverage?).
|
|
96
|
+
|
|
97
|
+
## Tests as spec
|
|
98
|
+
|
|
99
|
+
`tests/fullstackgtm*.test.ts` (at the **monorepo root**, run from there) map
|
|
100
|
+
one-to-one onto modules; `fullstackgtmSecurity.test.ts` pins the safety
|
|
101
|
+
invariants. Change apply/connector/integrity code → run the security suite.
|
package/docs/roadmap-to-1.0.md
CHANGED
|
@@ -106,7 +106,7 @@ The original thesis: GTM data disagrees across systems.
|
|
|
106
106
|
- Docs site with the operating-model registry as browsable reference.
|
|
107
107
|
- Performance pass: streaming snapshots for very large orgs.
|
|
108
108
|
|
|
109
|
-
## 0.10 → 0.
|
|
109
|
+
## 0.10 → 0.28 — the layers, as shipped
|
|
110
110
|
|
|
111
111
|
The plan above ended at the freeze; what shipped next grew the surface
|
|
112
112
|
outward, one layer per release, each consolidating before the next expanded:
|
|
@@ -129,9 +129,19 @@ outward, one layer per release, each consolidating before the next expanded:
|
|
|
129
129
|
- **0.24** — the schedule layer: horizontal cron, read/plan-side allowlist,
|
|
130
130
|
scheduling never auto-approves.
|
|
131
131
|
- **0.25** — agent skill distribution (`npx skills add fullstackgtm/core`).
|
|
132
|
+
- **0.25.2–0.26** — the security-hardening train: write-path integrity
|
|
133
|
+
(HMAC-signed approvals re-verified at apply; archive-of-duplicate and
|
|
134
|
+
irreversible-op drift guards; recovery snapshots) plus crontab/SSRF/XSS/
|
|
135
|
+
error-body/CSV/credential-mode fixes, each verified by adversarial re-attack.
|
|
136
|
+
- **0.27** — trust & transparency: `audit-log export|verify` (hash-chained,
|
|
137
|
+
signed apply-run record), SECURITY.md + DATA-FLOWS.md + company-of-record,
|
|
138
|
+
call-transcript insight grounding.
|
|
139
|
+
- **0.28** — connectors, credentials & supply chain: opt-in OS keychain,
|
|
140
|
+
broker-https enforcement, the build/CI dist-integrity gate (published dist is
|
|
141
|
+
provably from source), Salesforce-merge capability matrix.
|
|
132
142
|
|
|
133
143
|
The known-gaps list below predates these layers and has been re-verified
|
|
134
|
-
against the 0.
|
|
144
|
+
against the 0.28 surface: still accurate, still open.
|
|
135
145
|
|
|
136
146
|
## Known real-portal gaps to close before 1.0
|
|
137
147
|
|
package/llms.txt
CHANGED
|
@@ -15,6 +15,8 @@ at/above `--fail-on`.
|
|
|
15
15
|
- [README](https://github.com/fullstackgtm/core/blob/main/README.md): install, five-minute loop, auth ladder, MCP setup, programmatic use
|
|
16
16
|
- [INSTALL_FOR_AGENTS](https://github.com/fullstackgtm/core/blob/main/INSTALL_FOR_AGENTS.md): deterministic install-and-verify steps with expected outputs
|
|
17
17
|
- [Agent skill](https://github.com/fullstackgtm/core/blob/main/skills/fullstackgtm/SKILL.md): compact operating guide, installable via `npx skills add fullstackgtm/core`
|
|
18
|
+
- [Architecture](https://github.com/fullstackgtm/core/blob/main/docs/architecture.md): module map + snapshot → audit → plan → apply data flow; "where do I add a rule/connector/operation"
|
|
19
|
+
- [Contributing](https://github.com/fullstackgtm/core/blob/main/CONTRIBUTING.md): dev setup, the open-core mirror model, the release ritual
|
|
18
20
|
- [API reference](https://github.com/fullstackgtm/core/blob/main/docs/api.md): semver-covered surfaces — canonical model, rule interface, plan/apply contract, connector contract, config, CLI, MCP tools
|
|
19
21
|
- [CRM-health lifecycle](https://github.com/fullstackgtm/core/blob/main/docs/crm-health-lifecycle.md): the Prevent → Detect → Remediate → Verify/Attribute model; no-new-dupes design
|
|
20
22
|
- [CHANGELOG](https://github.com/fullstackgtm/core/blob/main/CHANGELOG.md): release history
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fullstackgtm",
|
|
3
|
-
"version": "0.28.
|
|
3
|
+
"version": "0.28.3",
|
|
4
4
|
"description": "Open-source agentic GTM ops framework: canonical GTM data model, pluggable deterministic audits, reviewable dry-run patch plans, approval-gated write-back with conflict detection, and cross-system entity resolution. HubSpot, Salesforce, and Stripe connectors included.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Full Stack GTM LLC <ryan@fullstackgtm.com> (https://fullstackgtm.com)",
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
"README.md",
|
|
30
30
|
"CHANGELOG.md",
|
|
31
31
|
"INSTALL_FOR_AGENTS.md",
|
|
32
|
+
"CONTRIBUTING.md",
|
|
32
33
|
"llms.txt",
|
|
33
34
|
"skills",
|
|
34
35
|
"LICENSE",
|
|
@@ -38,6 +39,7 @@
|
|
|
38
39
|
],
|
|
39
40
|
"scripts": {
|
|
40
41
|
"build": "rm -rf dist && tsc -p tsconfig.build.json",
|
|
42
|
+
"pretest": "test -d tests || { echo 'No tests/ in this directory. In the published mirror, tests live here and `npm test` works. In the monorepo, run package tests from the repo ROOT: `node --experimental-strip-types --test tests/fullstackgtm*.test.ts` (the tests live at the monorepo root tests/).' >&2; exit 1; }",
|
|
41
43
|
"test": "node --experimental-strip-types --test tests/*.test.ts",
|
|
42
44
|
"prepublishOnly": "npm run build"
|
|
43
45
|
},
|