feat: implement browser-ready intent factory and initialize project d…#103
feat: implement browser-ready intent factory and initialize project d…#103purushpsm147 wants to merge 2 commits intomainfrom
Conversation
…ocumentation and landing pages
📝 WalkthroughWalkthroughThis PR introduces "Blueprint" as a standard tier for short-session journeys alongside reframing "Enterprise" to emphasize persistent cross-session learning. Simultaneously, it changes Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
This PR updates the product/documentation narrative around Blueprint vs Enterprise (and privacy/consent posture), while also changing core runtime defaults so IntentManager is in-memory by default and browser persistence is explicitly opt-in (or provided via createBrowserIntent()).
Changes:
- Switched
IntentManagerdefault storage fromBrowserStorageAdapter(localStorage) toMemoryStorageAdapter(volatile), and madecreateBrowserIntent()explicitly injectBrowserStorageAdapter. - Updated core docs/READMEs and SDK package READMEs (React/Remix) to reflect the new default storage + privacy/consent framing.
- Updated tests and sandbox demos to explicitly use
BrowserStorageAdapterwhere persistence is required; refreshed marketing/pricing/landing copy around Blueprint vs Enterprise.
Reviewed changes
Copilot reviewed 25 out of 26 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/remix/README.md | Docs updated to describe new in-memory default and persistence opt-in. |
| packages/react/README.md | Docs updated to describe in-memory default and how to opt into persistence. |
| packages/core/tests/microkernel.test.mjs | Added coverage for createBrowserIntent() persistence across instances. |
| packages/core/tests/integration-contract.test.mjs | Updated integration tests to explicitly use BrowserStorageAdapter. |
| packages/core/tests/compatibility-matrix.test.mjs | Added test asserting IntentManager defaults to in-memory storage. |
| packages/core/src/types/events.ts | Clarified config docs for storageKey/namespace/storage defaults. |
| packages/core/src/factory.ts | createBrowserIntent() now explicitly wires BrowserStorageAdapter. |
| packages/core/src/engine/intent-manager.ts | Default storage changed to MemoryStorageAdapter. |
| packages/core/sandbox/app.ts | Sandbox now opts into browser persistence explicitly. |
| packages/core/sandbox/amazon/app.ts | Amazon sandbox now opts into browser persistence explicitly. |
| packages/core/package.json | Version bumped to 1.3.1. |
| packages/core/docs/architecture.md | Updated architecture/privacy docs to reflect storage-mode options. |
| packages/core/README.md | Updated README messaging and usage notes for new storage default. |
| packages/core/CHANGELOG.md | Added 1.3.1 entry describing the storage default change. |
| package-lock.json | Dependency lockfile updates. |
| marketing-cheatsheet.md | Updated positioning guidance for Blueprint vs persistence/enterprise. |
| landing/solutions.html | Updated enterprise bundle copy to reference Blueprint + persistent graph. |
| landing/marketing-cheatsheet.html | Updated calibration/blueprint messaging and storage-mode framing. |
| landing/llms.txt | Updated short LLM-oriented product copy and FAQs. |
| landing/llms-full.txt | Updated long LLM-oriented product copy and FAQs. |
| landing/licensing.html | Updated licensing/enterprise positioning language. |
| landing/index.html | Updated homepage FAQ and enterprise positioning snippets. |
| landing/ecommerce/index.html | Updated eCommerce landing privacy/consent FAQ copy. |
| landing/cheatsheet.html | Updated cheatsheet copy around learning mode and blueprint usage. |
| PRICING.md | Restructured pricing tiers and added blueprint-vs-enterprise FAQs. |
| Generate blueprint json/BaselineBluePrint.md | Added guidance on when to use Blueprints vs custom consolidation. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| { | ||
| "name": "@passiveintent/core", | ||
| "version": "1.3.0", | ||
| "version": "1.3.1", |
There was a problem hiding this comment.
Bumping @passiveintent/core from 1.3.0 to 1.3.1 (patch) seems inconsistent with the behavioral change that new IntentManager() no longer persists by default (localStorage → in-memory). If consumers relied on persistence without explicitly configuring storage, this is a breaking change; consider a minor/major bump per your versioning policy, or document a compatibility path (e.g., migration notes) if you intend to treat this as non-breaking.
| "version": "1.3.1", | |
| "version": "2.0.0", |
| persistDebounceMs: opts.persistDebounceMs, | ||
| persistThrottleMs: opts.persistThrottleMs, | ||
| storage: config.storage ?? new BrowserStorageAdapter(opts.namespace), | ||
| storage: config.storage ?? new MemoryStorageAdapter(), | ||
| asyncStorage: config.asyncStorage ?? null, | ||
| timer: this.timer, |
There was a problem hiding this comment.
This change makes IntentManager default to volatile in-memory storage instead of localStorage, which is an externally observable behavior change for anyone constructing new IntentManager() without specifying storage. The PR description focuses on docs/marketing updates; please call out this runtime behavior change explicitly in the PR description (and ensure release/versioning notes match the impact).
| `storage: new BrowserStorageAdapter()` when you want browser-local persistence | ||
| across reloads. |
There was a problem hiding this comment.
This section tells readers to pass storage: new BrowserStorageAdapter(), but doesn’t indicate where BrowserStorageAdapter comes from. Consider adding a short note or import hint (e.g. import from @passiveintent/core) to avoid confusion for Remix users following the README.
| `storage: new BrowserStorageAdapter()` when you want browser-local persistence | |
| across reloads. | |
| `storage: new BrowserStorageAdapter()` (import `BrowserStorageAdapter` from | |
| `@passiveintent/core`) when you want browser-local persistence across reloads. |
| reloads. Use `new BrowserStorageAdapter()` for browser `localStorage` | ||
| persistence. |
There was a problem hiding this comment.
This note references new BrowserStorageAdapter() but doesn’t mention how to import it. Adding a brief import example (from @passiveintent/core) would make the persistence opt-in path easier to follow.
| reloads. Use `new BrowserStorageAdapter()` for browser `localStorage` | |
| persistence. | |
| reloads. Import `BrowserStorageAdapter` from `@passiveintent/core` (for example, | |
| `import { BrowserStorageAdapter } from '@passiveintent/core'`) and use | |
| `new BrowserStorageAdapter()` for browser `localStorage` persistence. |
There was a problem hiding this comment.
Actionable comments posted: 7
🧹 Nitpick comments (7)
landing/llms.txt (1)
46-46: Consider consistency with asterisk usage.Same as noted in
index.html, the asterisk after "yes.*" might imply a footnote. The conditional explanation follows immediately, so the asterisk may be unnecessary.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@landing/llms.txt` at line 46, The trailing asterisk in the phrase "yes.*" is inconsistent with other docs and implies a missing footnote; update the text in landing/llms.txt by either removing the asterisk from "yes.*" or adding a corresponding footnote reference and marker, so the sentence "In the default zero-egress, in-memory deployment, yes." (or "yes[footnote]") and the following conditional explanation for PassiveIntent remain clear and consistent with index.html's asterisk usage.landing/index.html (1)
867-870: Consider clarifying or removing the asterisk marker.The FAQ answer includes "no.*" with an asterisk, but the subsequent text already provides the conditional explanation. The asterisk might imply there's a separate footnote that doesn't exist. Consider either:
- Removing the asterisk since the caveat immediately follows
- Adding a clear footnote reference if one is intended elsewhere
Suggested clarification
- For the default zero-egress, in-memory deployment, no.* If you enable persistent + For the default zero-egress, in-memory deployment, no. If you enable persistent🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@landing/index.html` around lines 867 - 870, The fragment contains a stray asterisk on the phrase "no.*" which implies a missing footnote; update the paragraph text that contains "For the default zero-egress, in-memory deployment, no.*" to either remove the asterisk (preferred) or add a matching footnote reference and footnote content explaining the caveat, ensuring the paragraph tag with that sentence and any related footnote markup (e.g., a footnote <sup> or an anchor/id and a corresponding footnote block) are updated so the marker and explanatory text are consistent.PRICING.md (1)
89-94: Consider simplifying "a small number of events" to "few events" for conciseness in the first FAQ answer.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@PRICING.md` around lines 89 - 94, Update the first FAQ answer in PRICING.md (the "We have short user sessions. Should we start with a Blueprint or an Enterprise engagement?" paragraph) by replacing the phrase "a small number of events per session" with the more concise "few events per session" so the sentence reads that a generic blueprint can be too coarse when users only generate few events per session.packages/core/docs/architecture.md (3)
215-216: Consider adding a clarifying note about when quota concerns apply.The section correctly scopes quota limits to
BrowserStorageAdapter, but users reading the "Known Limitations" section might not realize this limitation only applies if they opt into browser persistence.Consider adding a leading sentence:
### 3. `localStorage` quota limits +> **Note:** This limitation only applies when you explicitly use `BrowserStorageAdapter` or `createBrowserIntent()`. The default `MemoryStorageAdapter` is not subject to quota limits but data is cleared on page reload. + When `BrowserStorageAdapter` is active (directly or via `createBrowserIntent()`), `persist()` writes to `localStorage`. Browsers allow 5–10 MB per origin...This helps readers quickly assess whether this limitation affects their deployment.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/core/docs/architecture.md` around lines 215 - 216, Add a one-line clarifying lead that the quota/QuotaExceededError limitation applies only when browser persistence is used (i.e., when BrowserStorageAdapter is active or when createBrowserIntent() is used); update the paragraph that mentions persist(), onError, and getTelemetry().engineHealth to begin with this sentence so readers immediately know the quota note is relevant only if they opt into browser localStorage persistence.
2941-2950: Consider adding a table header or footnote explaining the "when enabled" conditions.The updated Verified Privacy Claims table now has conditional language ("browser-local when enabled") which is more accurate but may confuse readers who don't know what "enabled" means in this context.
Add a footnote reference to the table:
### Verified Privacy Claims The privacy properties of this library are not marketing copy. Here is how each claim is enforced and verifiable: | Claim | Verification | | ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **No network calls** | `grep -r "fetch\|XMLHttpRequest\|sendBeacon\|WebSocket" src/` returns zero results. The `package.json` has no runtime dependencies. The minified bundle can be audited in `dist/index.js`. | | **No fingerprinting** | No access to `navigator`, `screen`, `canvas`, `AudioContext`, or any known fingerprinting surface. EntropyGuard uses only `performance.now()` deltas from your own explicit `track()` calls. | | **No PII** | `track()` accepts a `string` label chosen entirely by the application. The library never reads cookies, URL query parameters, form fields, local storage keys other than `storageKey`, or any DOM content. | | **Browser-local when enabled**[^1] | Persistence routes exclusively through the `StorageAdapter` interface. Plain `new IntentManager()` uses the in-memory `MemoryStorageAdapter`; `createBrowserIntent()` and `storage: new BrowserStorageAdapter()` write to `localStorage`. Inspect the default persisted state at `localStorage.getItem('passiveintent:passive-intent')`. | | **Transparent & auditable** | `src/` is the exact code that ships. `tsup` minifies but does not inject code. Source maps in `dist/` make the minified output human-readable. | | **User can clear state**[^1] | When browser persistence is enabled, `localStorage.removeItem('passiveintent:passive-intent')` wipes all learned state. With the default in-memory adapter, a page reload clears it automatically. | | **Temporal data is non-persistent** | Dwell-time accumulators (`dwellStats`) are held in memory only and never written to `localStorage`. Per-state timing distributions cannot be reconstructed across sessions. | | **Zero runtime dependencies** | The dependency graph is empty — no transitive code paths can introduce egress, telemetry, or tracking. | [^1]: "Browser-local when enabled" means you must explicitly use `createBrowserIntent()` or inject `storage: new BrowserStorageAdapter()` in the config. The default `new IntentManager()` uses volatile in-memory storage that is cleared on page reload.This makes it immediately clear what "enabled" means without requiring readers to jump to another section.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/core/docs/architecture.md` around lines 2941 - 2950, Add a clarifying footnote and reference in the Verified Privacy Claims table to explain "when enabled": update the table row for "Browser-local when enabled" and the "User can clear state" row to include a footnote marker (e.g., [^1]), and add a footnote text that states: "Browser-local when enabled means you must explicitly call createBrowserIntent() or pass storage: new BrowserStorageAdapter() — the default new IntentManager() uses volatile in-memory storage cleared on reload." Reference the symbols createBrowserIntent(), BrowserStorageAdapter, and IntentManager in the footnote so readers can immediately understand how to enable persistence.
22-22: Verify consistency of "default" deployment language across all user-facing surfaces.The privacy guarantee now depends on users understanding the distinction between "default zero-egress, in-memory deployment" versus configurations that enable persistent storage or export. This conditional framing is more legally accurate but introduces complexity.
Consider adding a prominent callout box or admonition block immediately after this paragraph to make the distinction crystal clear:
**The core privacy guarantee:** PassiveIntent never sends behavioral data to PassiveIntent servers and never becomes your processor. It only observes the anonymous sequence of state labels your application explicitly provides. In the default zero-egress, in-memory deployment, no personal data leaves the device and the cleanest compliance posture applies. If you enable persistent browser storage or export graph data to your own infrastructure, your consent and controller obligations depend on your implementation and legal review. > **⚠️ Privacy Configuration Note:** > - **Default (zero-egress, in-memory):** No consent banner required, strictest privacy posture > - **With browser persistence enabled:** Assess local storage privacy implications with your counsel > - **With data export to your infrastructure:** Your controller obligations applyThis makes the conditional nature immediately visible rather than embedded in prose.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/core/docs/architecture.md` at line 22, Insert a prominent privacy-admonition block immediately after the paragraph that begins with "**The core privacy guarantee:**" to clearly distinguish the default "zero-egress, in-memory" deployment from configurations that enable browser persistence or data export; add the suggested callout content (a warning heading and three bullet lines: Default (zero-egress, in-memory): No consent banner required; With browser persistence enabled: Assess local storage privacy implications with counsel; With data export to your infrastructure: Your controller obligations apply) so readers see the conditional privacy posture up front without changing the original paragraph text.landing/llms-full.txt (1)
215-217: "Blueprint JSON" introduced without prior definition in this document.The FAQ answer references "Blueprint JSON" and "Persistent Graph Consolidator" as if they are established concepts, but neither term is defined or explained earlier in
llms-full.txt.Impact: LLM tools processing this document may not have sufficient context to answer user questions about Blueprints accurately.
Add a brief definition section before the FAQ or expand the "What PassiveIntent Does" section:
## What PassiveIntent Does PassiveIntent is a client-side JavaScript library that detects user hesitation and behavioral friction signals — pricing doubt, exit intent, trajectory drift, dwell-time anomalies — while the user is still in session and the decision is still in motion. **Deployment Options:** - **Core (AGPL)**: Single-session, in-memory intent detection. Cold-starts learn from scratch. - **Blueprint**: Pre-trained JSON graph for standard journeys (e.g., ecommerce checkout) that provides instant priors instead of cold-starting. - **Enterprise**: Persistent Graph Consolidator for custom, multi-session learning that compounds over time. The core insight: most analytics tools report on what happened after the drop-off. PassiveIntent acts during the session, while there is still an opportunity to intervene.This gives LLMs the necessary context to understand the Blueprint → Enterprise progression referenced in the FAQ.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@landing/llms-full.txt` around lines 215 - 217, Add a short definitions/deployment-options blurb before the FAQ (or expand the existing "What PassiveIntent Does" section) that defines "Blueprint JSON" as a pre-trained JSON graph providing instant priors for standard journeys and defines "Persistent Graph Consolidator" as the enterprise-level persistent aggregator for multi-session learning; include three bullet deployment options named Core (AGPL) — single-session in-memory, Blueprint — pre-trained JSON graphs for standard journeys, and Enterprise — Persistent Graph Consolidator for persistent cross-session learning, and then update the FAQ answer to reference the same exact term ("Blueprint" or "Blueprint JSON") used in the new section so the concepts are consistently defined and linked to the FAQ.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@landing/ecommerce/index.html`:
- Around line 897-899: Update the conflicting FAQ statement that currently reads
"No banner. No sensors. No PII export." so it matches the new conditional
compliance caveat: make the claim conditional for the default zero-egress
in-memory deployment and add a qualifier that persistent browser storage or
exporting graph data may create additional consent/privacy obligations; locate
and edit the HTML node containing that exact phrase ("No banner. No sensors. No
PII export.") and replace it with a conditional sentence consistent with the
paragraph referencing the default zero-egress behavior.
In `@landing/llms-full.txt`:
- Around line 218-223: Add a new FAQ entry that explicitly defines "Blueprint"
as a pre-trained Markov graph JSON artifact (e.g., common ecommerce checkout)
and states that Blueprints can be loaded into the Core engine to provide instant
priors instead of cold starts, that Blueprints are content/data (not a licensing
tier) and work with both Core (AGPL) and Enterprise, and that Enterprise is
required only when you need customer-specific learning that persists across
visits using Persistent Graph Consolidator; place this alongside the existing
Core vs Enterprise FAQ so it replaces the current ambiguity about Blueprint vs
Core.
- Line 207: Remove the orphaned asterisk from the FAQ answer line ("In the
default zero-egress, in-memory deployment, yes.*") and either inline the caveat
in that sentence (e.g., append "— this refers to the default new IntentManager()
in-memory setup which does not persist data") or add a matching footnote
definition at the end of the FAQ; update the same FAQ block in llms-full.txt so
the answer is self-contained and the asterisk no longer appears without a
corresponding note.
- Line 185: The enterprise extensions list missing the named product should be
updated: edit the line that currently reads "Enterprise extensions for
repeat-visit continuity, multi-tab orchestration, cross-domain journeys, and
dynamic baseline calibration are included" to include "Persistent Graph
Consolidator" alongside the existing features so it matches licensing/FAQ
wording; locate the phrase in the file (the enterprise extensions list) and
insert "Persistent Graph Consolidator" in the same comma-separated list, keeping
punctuation and capitalization consistent with the other feature names.
- Around line 167-170: Update the marketing copy for the "Cookie-free" and
"Compliance-friendly by design" bullets to match the architecture precision:
explicitly state the default behavior is in-memory (no persistent browser
storage or cookies), make clear that persistent browser storage or exporting
graph data is an opt-in/deployer-controlled action that may create
consent/controller obligations, and reword the "compliance-friendly" line to say
it is compliance-friendly for default zero-egress, in-memory deployments while
requiring deployers to assess GDPR/consent implications when they enable
persistence or data export; keep the wording concise and user-facing but include
the default and opt-in/consenter condition.
In `@landing/marketing-cheatsheet.html`:
- Around line 149-160: Change the contradictory opening sentence "The thresholds
below assume a calibrated baseline." to explicitly state that thresholds are
provisional until calibration or persistent storage is enabled; update the
paragraph containing that sentence so it reads that the displayed thresholds are
estimates based on a calibrated baseline only if persistent cross-session
learning or Blueprint JSON has been enabled, otherwise the engine starts from
raw Markov probabilities and results are tab-scoped/ephemeral. Ensure you edit
the exact sentence "The thresholds below assume a calibrated baseline." and the
following paragraph that begins "The engine starts from raw Markov
probabilities..." so the two lines consistently communicate that thresholds
require calibration or persistent storage/Blueprint to be directly usable.
In `@packages/core/CHANGELOG.md`:
- Around line 17-23: The changelog entry incorrectly labels a breaking
behavioral change (IntentManager default storage switching to
MemoryStorageAdapter) as a patch; update the release to a breaking/minor version
and/or restore the previous default to avoid silent data-loss for existing
consumers. Specifically, adjust the release version from 1.3.1 to a breaking
bump (e.g., 2.0.0) in the changelog and release metadata, or revert the
constructor behavior of IntentManager so new IntentManager() still uses
BrowserStorageAdapter by default; also ensure createBrowserIntent() continues to
inject BrowserStorageAdapter explicitly and update the notes to reflect
whichever approach you choose (IntentManager, MemoryStorageAdapter,
BrowserStorageAdapter, createBrowserIntent).
---
Nitpick comments:
In `@landing/index.html`:
- Around line 867-870: The fragment contains a stray asterisk on the phrase
"no.*" which implies a missing footnote; update the paragraph text that contains
"For the default zero-egress, in-memory deployment, no.*" to either remove the
asterisk (preferred) or add a matching footnote reference and footnote content
explaining the caveat, ensuring the paragraph tag with that sentence and any
related footnote markup (e.g., a footnote <sup> or an anchor/id and a
corresponding footnote block) are updated so the marker and explanatory text are
consistent.
In `@landing/llms-full.txt`:
- Around line 215-217: Add a short definitions/deployment-options blurb before
the FAQ (or expand the existing "What PassiveIntent Does" section) that defines
"Blueprint JSON" as a pre-trained JSON graph providing instant priors for
standard journeys and defines "Persistent Graph Consolidator" as the
enterprise-level persistent aggregator for multi-session learning; include three
bullet deployment options named Core (AGPL) — single-session in-memory,
Blueprint — pre-trained JSON graphs for standard journeys, and Enterprise —
Persistent Graph Consolidator for persistent cross-session learning, and then
update the FAQ answer to reference the same exact term ("Blueprint" or
"Blueprint JSON") used in the new section so the concepts are consistently
defined and linked to the FAQ.
In `@landing/llms.txt`:
- Line 46: The trailing asterisk in the phrase "yes.*" is inconsistent with
other docs and implies a missing footnote; update the text in landing/llms.txt
by either removing the asterisk from "yes.*" or adding a corresponding footnote
reference and marker, so the sentence "In the default zero-egress, in-memory
deployment, yes." (or "yes[footnote]") and the following conditional explanation
for PassiveIntent remain clear and consistent with index.html's asterisk usage.
In `@packages/core/docs/architecture.md`:
- Around line 215-216: Add a one-line clarifying lead that the
quota/QuotaExceededError limitation applies only when browser persistence is
used (i.e., when BrowserStorageAdapter is active or when createBrowserIntent()
is used); update the paragraph that mentions persist(), onError, and
getTelemetry().engineHealth to begin with this sentence so readers immediately
know the quota note is relevant only if they opt into browser localStorage
persistence.
- Around line 2941-2950: Add a clarifying footnote and reference in the Verified
Privacy Claims table to explain "when enabled": update the table row for
"Browser-local when enabled" and the "User can clear state" row to include a
footnote marker (e.g., [^1]), and add a footnote text that states:
"Browser-local when enabled means you must explicitly call createBrowserIntent()
or pass storage: new BrowserStorageAdapter() — the default new IntentManager()
uses volatile in-memory storage cleared on reload." Reference the symbols
createBrowserIntent(), BrowserStorageAdapter, and IntentManager in the footnote
so readers can immediately understand how to enable persistence.
- Line 22: Insert a prominent privacy-admonition block immediately after the
paragraph that begins with "**The core privacy guarantee:**" to clearly
distinguish the default "zero-egress, in-memory" deployment from configurations
that enable browser persistence or data export; add the suggested callout
content (a warning heading and three bullet lines: Default (zero-egress,
in-memory): No consent banner required; With browser persistence enabled: Assess
local storage privacy implications with counsel; With data export to your
infrastructure: Your controller obligations apply) so readers see the
conditional privacy posture up front without changing the original paragraph
text.
In `@PRICING.md`:
- Around line 89-94: Update the first FAQ answer in PRICING.md (the "We have
short user sessions. Should we start with a Blueprint or an Enterprise
engagement?" paragraph) by replacing the phrase "a small number of events per
session" with the more concise "few events per session" so the sentence reads
that a generic blueprint can be too coarse when users only generate few events
per session.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: c9795fea-e4cc-420d-b8bd-b58081fad084
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (25)
Generate blueprint json/BaselineBluePrint.mdPRICING.mdlanding/cheatsheet.htmllanding/ecommerce/index.htmllanding/index.htmllanding/licensing.htmllanding/llms-full.txtlanding/llms.txtlanding/marketing-cheatsheet.htmllanding/solutions.htmlmarketing-cheatsheet.mdpackages/core/CHANGELOG.mdpackages/core/README.mdpackages/core/docs/architecture.mdpackages/core/package.jsonpackages/core/sandbox/amazon/app.tspackages/core/sandbox/app.tspackages/core/src/engine/intent-manager.tspackages/core/src/factory.tspackages/core/src/types/events.tspackages/core/tests/compatibility-matrix.test.mjspackages/core/tests/integration-contract.test.mjspackages/core/tests/microkernel.test.mjspackages/react/README.mdpackages/remix/README.md
| For the default zero-egress, in-memory deployment, no.* If you enable persistent | ||
| browser storage or export graph data to your own infrastructure, your consent and | ||
| privacy obligations depend on your implementation and legal review. |
There was a problem hiding this comment.
Align the rest of the page with this new compliance caveat.
This FAQ now correctly makes banner/privacy obligations conditional, but the same page still says “No banner. No sensors. No PII export.” at Line 826. Leaving both claims in one page gives readers conflicting compliance guidance and undermines the clarification this PR is adding.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@landing/ecommerce/index.html` around lines 897 - 899, Update the conflicting
FAQ statement that currently reads "No banner. No sensors. No PII export." so it
matches the new conditional compliance caveat: make the claim conditional for
the default zero-egress in-memory deployment and add a qualifier that persistent
browser storage or exporting graph data may create additional consent/privacy
obligations; locate and edit the HTML node containing that exact phrase ("No
banner. No sensors. No PII export.") and replace it with a conditional sentence
consistent with the paragraph referencing the default zero-egress behavior.
| - **Cookie-free**: Does not set or read any cookies. Browser storage is optional and deployer-controlled. | ||
| - **No fingerprinting**: Does not use browser fingerprinting techniques. | ||
| - **GDPR/CCPA compatible**: Because no personal data is collected or transmitted, PassiveIntent does not require a consent banner to function. | ||
| - **Compliance-friendly by design**: The default zero-egress, in-memory deployment avoids third-party behavioral export. If you enable persistent browser storage or export graph data to your own infrastructure, assess your own consent and controller obligations. | ||
| - **Zero Egress Attestation**: A formal PDF attestation is available at https://passiveintent.dev/PassiveIntent_Zero_Egress_Attestation.pdf |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
Inconsistent privacy messaging between marketing and technical docs.
The LLM content (marketing) says "Cookie-free: Does not set or read any cookies. Browser storage is optional and deployer-controlled" while architecture.md provides much more detailed conditional language about consent obligations.
Issue: Marketing language is simpler but potentially misleading:
- "Browser storage is optional" suggests a choice, but doesn't clarify default behavior
- Doesn't mention that default is in-memory (no persistence)
- Line 169 says "compliance-friendly by design" which is vague compared to architecture.md's precise GDPR article mapping
Align the marketing language with the technical precision without losing readability:
## Privacy & Compliance
- **Zero-egress by default**: All behavioral computation runs in the browser. No behavioral data is transmitted to PassiveIntent servers or any third party.
-- **Cookie-free**: Does not set or read any cookies. Browser storage is optional and deployer-controlled.
+- **Cookie-free**: Does not set or read any cookies. Persistence defaults to in-memory (cleared on reload); browser storage is an explicit opt-in via `createBrowserIntent()`.
- **No fingerprinting**: Does not use browser fingerprinting techniques.
-- **Compliance-friendly by design**: The default zero-egress, in-memory deployment avoids third-party behavioral export. If you enable persistent browser storage or export graph data to your own infrastructure, assess your own consent and controller obligations.
+- **Default: No consent required**: The default zero-egress, in-memory deployment processes no personal data and requires no consent banner. Enabling persistent browser storage or exporting graph data to your infrastructure may trigger consent obligations—assess with your counsel.
- **Zero Egress Attestation**: A formal PDF attestation is available at https://passiveintent.dev/PassiveIntent_Zero_Egress_Attestation.pdfThis is clearer about:
- What the default is (in-memory, not persistent)
- When consent obligations apply (opt-in scenarios)
- Making the "no consent required" claim explicit for the default case
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@landing/llms-full.txt` around lines 167 - 170, Update the marketing copy for
the "Cookie-free" and "Compliance-friendly by design" bullets to match the
architecture precision: explicitly state the default behavior is in-memory (no
persistent browser storage or cookies), make clear that persistent browser
storage or exporting graph data is an opt-in/deployer-controlled action that may
create consent/controller obligations, and reword the "compliance-friendly" line
to say it is compliance-friendly for default zero-egress, in-memory deployments
while requiring deployers to assess GDPR/consent implications when they enable
persistence or data export; keep the wording concise and user-facing but include
the default and opt-in/consenter condition.
| - Required to run PassiveIntent as a network service without releasing your full application source under AGPL | ||
| - Required for OEM/agency/wrapped-product scenarios | ||
| - Enterprise extensions (multi-session, multi-tab, cross-domain, dynamic baseline) are included | ||
| - Enterprise extensions for repeat-visit continuity, multi-tab orchestration, cross-domain journeys, and dynamic baseline calibration are included |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Search for all mentions of enterprise features across landing pages
rg -i 'enterprise.*feature|persistent.*graph|multi-tab|cross-domain|baseline.*calibration' landing/
# Check if there's a canonical enterprise features list in pricing docs
fd -e md -e html -e txt . landing/ | xargs rg -l 'Enterprise.*includes|What.*Enterprise.*adds'Repository: passiveintent/core
Length of output: 6477
Add "Persistent Graph Consolidator" to enterprise extensions list for consistency with FAQ and licensing documentation.
Line 185 lists enterprise extensions but omits "Persistent Graph Consolidator," which is explicitly named throughout the documentation (licensing.html, FAQ sections, and solutions pages) as a key enterprise differentiator. The current list describes capabilities but is missing this product feature name. Update line 185 to include it alongside the existing features.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@landing/llms-full.txt` at line 185, The enterprise extensions list missing
the named product should be updated: edit the line that currently reads
"Enterprise extensions for repeat-visit continuity, multi-tab orchestration,
cross-domain journeys, and dynamic baseline calibration are included" to include
"Persistent Graph Consolidator" alongside the existing features so it matches
licensing/FAQ wording; locate the phrase in the file (the enterprise extensions
list) and insert "Persistent Graph Consolidator" in the same comma-separated
list, keeping punctuation and capitalization consistent with the other feature
names.
|
|
||
| Q: Is it cookie-free and GDPR-compliant? | ||
| A: Yes. PassiveIntent does not use cookies or browser fingerprinting. No personally identifiable information is collected or transmitted. No consent banner is required for the library itself to function. | ||
| A: In the default zero-egress, in-memory deployment, yes.* PassiveIntent does not use cookies or browser fingerprinting, and PassiveIntent does not receive the data. If you enable persistent browser storage or export graph data to your own infrastructure, your consent and controller obligations depend on your implementation and counsel. |
There was a problem hiding this comment.
Orphaned asterisk in FAQ answer needs clarification.
The answer "In the default zero-egress, in-memory deployment, yes.*" includes an asterisk that suggests a footnote, but no corresponding footnote is provided in the FAQ section.
Suggested fix for clarity
Option 1: Remove the asterisk and incorporate the caveat inline:
Q: Is it cookie-free and GDPR-compliant?
-A: In the default zero-egress, in-memory deployment, yes.* PassiveIntent does not use cookies or browser fingerprinting, and PassiveIntent does not receive the data. If you enable persistent browser storage or export graph data to your own infrastructure, your consent and controller obligations depend on your implementation and counsel.
+A: **Yes, by default.** PassiveIntent does not use cookies or browser fingerprinting, and in the default zero-egress, in-memory deployment, PassiveIntent does not receive any data. If you enable persistent browser storage or export graph data to your own infrastructure, your consent and controller obligations depend on your implementation and counsel.Option 2: Add an actual footnote section at the end of the FAQ:
---
*Default deployment means `new IntentManager()` without explicit storage adapter configuration, which uses volatile in-memory storage cleared on page reload.Option 1 is cleaner for a FAQ format where readers expect self-contained answers.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@landing/llms-full.txt` at line 207, Remove the orphaned asterisk from the FAQ
answer line ("In the default zero-egress, in-memory deployment, yes.*") and
either inline the caveat in that sentence (e.g., append "— this refers to the
default new IntentManager() in-memory setup which does not persist data") or add
a matching footnote definition at the end of the FAQ; update the same FAQ block
in llms-full.txt so the answer is self-contained and the asterisk no longer
appears without a corresponding note.
| Q: When do teams usually move from the core to enterprise? | ||
| A: Usually when Blueprint baselines and live-session memory are no longer enough. The trigger is often an analytics or data team asking the engine to retain and compound customer-specific learning over a longer horizon instead of resetting to a generic prior. That is where Persistent Graph Consolidator becomes the right commercial step. | ||
|
|
||
| Q: What is the difference between PassiveIntent Core and the Enterprise pack? | ||
| A: Core is the AGPL open-source engine for one live session on one site in one tab. Enterprise expands that for repeat visits, connected properties, tab-heavy research flows, and fast-changing traffic conditions using dynamic baseline calibration (Z-score normalization against your site's own μ/σ). | ||
| A: Core is the AGPL open-source engine for one live session on one site in one tab. If a standard journey only needs a faster start, use a Blueprint. Enterprise expands that for repeat visits, connected properties, custom short-session funnels, and fast-changing traffic conditions using persistent continuity and dynamic baseline calibration (Z-score normalization against your site's own μ/σ). | ||
|
|
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
Clarify Blueprint positioning in the Core → Enterprise progression.
The FAQ answers create some ambiguity about where "Blueprint" fits:
- Line 216-217: "start with a Blueprint JSON" (suggests Core + Blueprint)
- Line 219: "Blueprint baselines and live-session memory" (suggests these are Core capabilities)
- Line 222: "If a standard journey only needs a faster start, use a Blueprint" (suggests Blueprint is distinct from Core)
Question: Is Blueprint:
- A feature available in Core (pre-trained JSON graphs you can load)?
- A separate tier between Core and Enterprise?
- A deployment pattern available in both Core and Enterprise?
Add a FAQ entry that explicitly positions Blueprint:
Q: What is a Blueprint, and how does it relate to Core vs Enterprise?
A: A Blueprint is a pre-trained Markov graph JSON file for common user journeys (e.g., standard ecommerce checkout). Blueprints can be loaded into the Core engine to provide instant priors instead of cold-starting from zero. They work with both Core (AGPL) and Enterprise licenses. If your journey matches a standard Blueprint, you can use Core + Blueprint. If you need customer-specific learning that persists across visits, you need Enterprise with Persistent Graph Consolidator.This makes the relationship explicit: Blueprint is a content/data artifact, not a licensing tier.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@landing/llms-full.txt` around lines 218 - 223, Add a new FAQ entry that
explicitly defines "Blueprint" as a pre-trained Markov graph JSON artifact
(e.g., common ecommerce checkout) and states that Blueprints can be loaded into
the Core engine to provide instant priors instead of cold starts, that
Blueprints are content/data (not a licensing tier) and work with both Core
(AGPL) and Enterprise, and that Enterprise is required only when you need
customer-specific learning that persists across visits using Persistent Graph
Consolidator; place this alongside the existing Core vs Enterprise FAQ so it
replaces the current ambiguity about Blueprint vs Core.
| The thresholds below assume a calibrated baseline. The engine starts from raw Markov | ||
| probabilities, and how quickly it accumulates organic learning depends on your privacy | ||
| and storage mode. | ||
| </p> | ||
| <p> | ||
| For best accuracy, ensure your integration includes a calibration step before applying | ||
| hard intervention rules in production. | ||
| In zero-consent, ephemeral deployments, the model resets with the tab. In that setup, | ||
| Blueprint JSON is the practical path to instant, high-sensitivity funnel enforcement. | ||
| </p> | ||
| <p> | ||
| Teams that want cross-session organic baseline learning can either enable persistent | ||
| storage under their own ePrivacy and cookie compliance policy or move to Enterprise | ||
| Persistent Graph Consolidator. |
There was a problem hiding this comment.
The calibration note contradicts itself.
Line 149 says the matrix assumes a calibrated baseline, but the rest of the section explains that the engine starts from raw probabilities and may stay tab-scoped unless Blueprint or persistent storage is enabled. That makes the opening sentence read as if these thresholds are directly usable out of the box, which is the opposite of the clarification below.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@landing/marketing-cheatsheet.html` around lines 149 - 160, Change the
contradictory opening sentence "The thresholds below assume a calibrated
baseline." to explicitly state that thresholds are provisional until calibration
or persistent storage is enabled; update the paragraph containing that sentence
so it reads that the displayed thresholds are estimates based on a calibrated
baseline only if persistent cross-session learning or Blueprint JSON has been
enabled, otherwise the engine starts from raw Markov probabilities and results
are tab-scoped/ephemeral. Ensure you edit the exact sentence "The thresholds
below assume a calibrated baseline." and the following paragraph that begins
"The engine starts from raw Markov probabilities..." so the two lines
consistently communicate that thresholds require calibration or persistent
storage/Blueprint to be directly usable.
| ## [1.3.1] - 2026-04-16 | ||
|
|
||
| ### Changed | ||
|
|
||
| - **`IntentManager` now defaults to `MemoryStorageAdapter`** — constructing `new IntentManager()` without a `storage` override no longer writes to `localStorage`. State is kept in a volatile, Map-backed adapter and is discarded on reload, making direct construction side-effect-free by default. | ||
|
|
||
| - **`createBrowserIntent()` now injects `BrowserStorageAdapter` explicitly** — the Layer 3 web factory still provides browser-local persistence out of the box. If you construct `IntentManager` directly and need cross-session browser storage, pass `storage: new BrowserStorageAdapter()`. |
There was a problem hiding this comment.
This is a breaking change, not a patch release.
Switching new IntentManager() from persistent browser storage to volatile in-memory storage changes default runtime behavior for existing consumers. Shipping that as 1.3.1 will let patch-level upgraders silently lose cross-session learning, so this needs a breaking-version bump or the old default restored.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/core/CHANGELOG.md` around lines 17 - 23, The changelog entry
incorrectly labels a breaking behavioral change (IntentManager default storage
switching to MemoryStorageAdapter) as a patch; update the release to a
breaking/minor version and/or restore the previous default to avoid silent
data-loss for existing consumers. Specifically, adjust the release version from
1.3.1 to a breaking bump (e.g., 2.0.0) in the changelog and release metadata, or
revert the constructor behavior of IntentManager so new IntentManager() still
uses BrowserStorageAdapter by default; also ensure createBrowserIntent()
continues to inject BrowserStorageAdapter explicitly and update the notes to
reflect whichever approach you choose (IntentManager, MemoryStorageAdapter,
BrowserStorageAdapter, createBrowserIntent).
This pull request updates documentation and marketing pages to clarify the differences between Blueprint and Enterprise offerings, especially for teams with short user sessions or custom funnels. It emphasizes when to use a prebuilt Blueprint baseline versus engaging for a custom, persistent solution, and updates language around privacy, consent, and enterprise features across pricing, FAQs, and product pages.
Key changes:
Blueprint vs. Enterprise Positioning:
BaselineBluePrint.mdexplaining when to use a standard Blueprint JSON versus a custom consolidation (Persistent Graph Consolidator), clarifying the recommended approach for short-session and highly specialized journeys.Pricing and Feature Tier Clarification:
PRICING.mdas separate sections for each tier, with clearer descriptions of what each tier includes and when to consider Enterprise, including Persistent Graph Consolidator and Blueprint options.Privacy and Consent Language:
Technical and Product Explanation Improvements:
Enterprise Feature Details:
These updates make it easier for prospective users to understand the right entry point for their needs, the privacy posture of each deployment mode, and the path to advanced enterprise features.…ocumentation and landing pages
Description
Type of change
Checklist
npm run lintandnpm run typechecklocallynpm run test:unit -w @passiveintent/core)Summary by CodeRabbit
New Features
Changed
Documentation