{
  "featureName": "lite-entry-point",
  "branchName": "feat/lite-entry-point",
  "baseBranch": "main",
  "createdAt": "2026-03-18",
  "status": "Draft — Rev 2 (Thing Rev 1 fixes)",
  "maxIterations": 14,
  "stories": [
    {
      "id": "story-1",
      "title": "Lite source files: AvoSchemaParserLite + AvoNetworkCallsHandlerLite",
      "approach": "general-purpose",
      "dependencies": [],
      "files": {
        "create": [
          "src/lite/AvoSchemaParserLite.ts",
          "src/lite/AvoNetworkCallsHandlerLite.ts"
        ],
        "modify": []
      },
      "implementationNotes": [
        "Create src/lite/ directory first: mkdir -p src/lite (directory does not exist in the repo)",
        "AvoSchemaParserLite: remove encryptValue import; change types import to from './AvoNetworkCallsHandlerLite'; delete canSendEncryptedValues, getEncryptedPropertyValueIfEnabled methods; in extractSchema remove canSendEncryptedValues variable and encryptedValue block; keep method signature accepting publicEncryptionKey and env params (accepted but unused)",
        "AvoNetworkCallsHandlerLite: change AvoInspector import to AvoInspectorLite as AvoInspector; change AvoGuid import to '../AvoGuid'; change AvoStreamId import to AvoStreamIdLite as AvoStreamId from './AvoStreamIdLite'; change EventSpecMetadata import to '../eventSpec/AvoEventSpecFetchTypes'",
        "Both files: add LITE COPY header comment: '// LITE COPY of src/<OriginalFile>.ts\\n// Sync obligation: any change to src/<OriginalFile>.ts must be reviewed for applicability here.\\n// Diff against original: git diff HEAD src/<OriginalFile>.ts src/lite/<LiteCopyFile>.ts'",
        "Build will not pass until Story 3 completes (AvoInspectorLite not yet created); ts-jest will fail to compile AvoNetworkCallsHandlerLite.ts due to forward import of AvoInspectorLite — tests and browser tests are non-required for this reason"
      ],
      "qualityChecks": {
        "build": {
          "command": "yarn build",
          "required": false,
          "note": "Expected to fail until Story 3 — AvoInspectorLite not yet created"
        },
        "tests": {
          "command": "yarn test --roots='<rootDir>/src'",
          "required": false,
          "note": "Non-required — ts-jest will fail to compile AvoNetworkCallsHandlerLite.ts due to forward import of AvoInspectorLite which does not exist until Story 3"
        },
        "browserTests": {
          "command": "BROWSER=1 yarn test --roots='<rootDir>/src'",
          "required": false,
          "note": "Non-required — same ts-jest forward-import constraint applies"
        }
      }
    },
    {
      "id": "story-2",
      "title": "Lite source files: AvoStreamIdLite + AvoDeduplicatorLite + AvoBatcherLite",
      "approach": "general-purpose",
      "dependencies": ["story-1"],
      "files": {
        "create": [
          "src/lite/AvoStreamIdLite.ts",
          "src/lite/AvoDeduplicatorLite.ts",
          "src/lite/AvoBatcherLite.ts"
        ],
        "modify": []
      },
      "implementationNotes": [
        "AvoStreamIdLite: change AvoInspector import to AvoInspectorLite as AvoInspector from './AvoInspectorLite'; change AvoGuid import to '../AvoGuid'; alias as AvoInspector means zero body changes",
        "AvoDeduplicatorLite: change AvoSchemaParser import to AvoSchemaParserLite as AvoSchemaParser from './AvoSchemaParserLite'; change deepEquals import to '../utils'; alias as AvoSchemaParser means zero body changes",
        "AvoBatcherLite: change AvoInspector import to AvoInspectorLite as AvoInspector from './AvoInspectorLite'; change AvoNetworkCallsHandler import to from './AvoNetworkCallsHandlerLite'; change EventSpecMetadata import to '../eventSpec/AvoEventSpecFetchTypes'; keep eventSpecMetadata? in AvoBatcherType interface",
        "All three files: add LITE COPY header comment",
        "Build still not expected to pass cleanly until Story 3"
      ],
      "qualityChecks": {
        "build": {
          "command": "yarn build",
          "required": false,
          "note": "Expected to fail until Story 3 — AvoInspectorLite not yet created"
        },
        "tests": {
          "command": "yarn test --roots='<rootDir>/src'",
          "required": false,
          "note": "Non-required — ts-jest will fail to compile lite files that forward-import AvoInspectorLite, which does not exist until Story 3"
        },
        "browserTests": {
          "command": "BROWSER=1 yarn test --roots='<rootDir>/src'",
          "required": false,
          "note": "Non-required — same ts-jest forward-import constraint applies"
        }
      }
    },
    {
      "id": "story-3",
      "title": "AvoInspectorLite + index + tsconfig.lite.json + package.json",
      "approach": "general-purpose",
      "dependencies": ["story-1", "story-2"],
      "files": {
        "create": [
          "src/lite/AvoInspectorLite.ts",
          "src/lite/index.ts",
          "tsconfig.lite.json"
        ],
        "modify": [
          "package.json"
        ]
      },
      "implementationNotes": [
        "AvoInspectorLite imports: AvoInspectorEnv from '../AvoInspectorEnv'; AvoSchemaParserLite from './AvoSchemaParserLite'; AvoBatcherLite as AvoBatcher from './AvoBatcherLite'; AvoNetworkCallsHandlerLite as AvoNetworkCallsHandler + EventProperty type from './AvoNetworkCallsHandlerLite'; AvoStorage from '../AvoStorage'; AvoDeduplicatorLite as AvoDeduplicator from './AvoDeduplicatorLite'; AvoStreamIdLite as AvoStreamId from './AvoStreamIdLite'; isValueEmpty from '../utils'; libVersion = require('../../package.json').version",
        "Constructor options: { apiKey, env, version, appName?, suffix? } — no publicEncryptionKey",
        "Constructor body: no this.publicEncryptionKey assignment; no this.streamId field or assignment; no if(this.streamId) eventSpec init block; pass undefined as 6th arg to new AvoNetworkCallsHandlerLite(..., undefined)",
        "Static fields: avoStorage, _batchSize (get+set), _batchFlushSeconds (get only — no static setter), _shouldLog (get+set), _networkTimeout (get+set) — exactly mirroring the full class",
        "trackSchemaFromEvent: no fetchAndValidateEvent, no validationResult branch; always calls trackSchemaInternal directly",
        "_avoFunctionTrackSchemaFromEvent: mirrors trackSchemaFromEvent but shouldRegisterEvent(name, params, true) and forwards eventId/eventHash",
        "trackSchema: identical to full but without await this.fetchEventSpecIfNeeded(eventName)",
        "extractSchema: calls AvoSchemaParserLite.extractSchema(eventProperties) — no key, no env",
        "src/lite/index.ts: export { AvoInspectorLite as AvoInspector } from './AvoInspectorLite'; export { AvoInspectorEnv, type AvoInspectorEnvType, type AvoInspectorEnvValueType } from '../AvoInspectorEnv'",
        "tsconfig.lite.json: extends tsconfig.json; outDir ./dist; include: src/lite/**/* + src/AvoInspectorEnv.ts + src/AvoStorage.ts + src/AvoGuid.ts + src/utils.ts + src/eventSpec/AvoEventSpecFetchTypes.ts",
        "package.json: add files:[dist,bin]; add exports map with . and ./lite each having types and default conditions; update build script to add && tsc --project tsconfig.lite.json --noEmit before webpack; add check:lite-size and verify:lite-sync scripts; update prepublishOnly to append && yarn check:lite-size && yarn verify:lite-sync so the size gate and drift check are publish-blocking",
        "Post-story verification: grep -r 'AvoEncryption' dist/lite/ must return no matches; same for AvoEventSpecFetcher, noble, EventSpecCache"
      ],
      "qualityChecks": {
        "build": {
          "command": "yarn build",
          "required": true
        },
        "tests": {
          "command": "yarn test --roots='<rootDir>/src'",
          "required": true
        },
        "browserTests": {
          "command": "BROWSER=1 yarn test --roots='<rootDir>/src'",
          "required": true
        }
      }
    },
    {
      "id": "story-4",
      "title": "Tests for lite build",
      "approach": "general-purpose",
      "dependencies": ["story-3"],
      "files": {
        "create": [
          "src/__tests__/AvoInspectorLite_test.ts",
          "src/__tests__/AvoSchemaParserLite_test.ts"
        ],
        "modify": []
      },
      "implementationNotes": [
        "AvoInspectorLite_test.ts test cases: (1) constructor accepts apiKey/env/version/appName/suffix; (2) publicEncryptionKey causes TS error via @ts-expect-error; (3) trackSchemaFromEvent returns schema with no encryptedPropertyValue; (4) trackSchemaFromEvent returns [] for deduplicated events; (5) trackSchema completes without throwing; (6) extractSchema returns correct schema; (7) static getters batchSize/batchFlushSeconds/shouldLog/networkTimeout readable; (8) setters for batchSize/shouldLog/networkTimeout work; batchFlushSeconds set only via setBatchFlushSeconds(n); (9) import from src/lite/index.ts exports AvoInspector and AvoInspectorEnv; (10) static isolation: AvoInspector.batchSize = 99 does NOT change AvoInspectorLite.batchSize",
        "AvoSchemaParserLite_test.ts: (1) correct property types; (2) never sets encryptedPropertyValue even if publicEncryptionKey passed; (3) nested objects extracted; (4) arrays/lists extracted",
        "Mock XMLHttpRequest following pattern in AvoInspectorEventSpec_test.ts",
        "Use defaultOptions from src/__tests__/constants.ts as base",
        "Static isolation test pattern: AvoInspector.batchSize = 99; expect(AvoInspectorLite.batchSize).not.toBe(99); AvoInspector.batchSize = 30"
      ],
      "qualityChecks": {
        "build": {
          "command": "yarn build",
          "required": true
        },
        "tests": {
          "command": "yarn test --roots='<rootDir>/src'",
          "required": true
        },
        "browserTests": {
          "command": "BROWSER=1 yarn test --roots='<rootDir>/src'",
          "required": true
        }
      }
    },
    {
      "id": "story-5",
      "title": "Drift detection and size verification scripts",
      "approach": "general-purpose",
      "dependencies": ["story-3"],
      "files": {
        "create": [
          "scripts/verify-lite-sync.sh",
          "scripts/check-lite-size.js",
          "scripts/webpack.lite-size.config.js"
        ],
        "modify": []
      },
      "implementationNotes": [
        "Create scripts/ directory with mkdir -p scripts before writing files",
        "verify-lite-sync.sh: PAIRS array with 4 pairs (AvoNetworkCallsHandler/Lite, AvoBatcher/Lite, AvoStreamId/Lite, AvoDeduplicator/Lite); add comment above PAIRS: '# AvoSchemaParser is excluded: AvoSchemaParserLite removes entire methods (encryption), not just one import line. Drift there requires manual review.'; fail if any pair has >10 changed lines; make script executable",
        "check-lite-size.js: before running webpack call fs.mkdirSync(path.resolve(__dirname, '../test-bundle-size/output'), { recursive: true }) to guard against missing output directory on fresh clones (mirrors defensive mkdir -p in existing analyze.sh); then execSync webpack with scripts/webpack.lite-size.config.js; then run terser on test-bundle-size/output/bundle-lite.js writing to bundle-lite-terser.js; gzip and fail if > 7168 bytes (7 KB)",
        "webpack.lite-size.config.js: entry ./dist/lite/index.js; output bundle-lite.js in test-bundle-size/output/; mode production; no ts-loader (pre-compiled JS); libraryTarget umd; splitChunks false",
        "verify-lite-sync.sh must have shebang #!/usr/bin/env bash and be chmod +x",
        "package.json scripts were already added in Story 3 (check:lite-size and verify:lite-sync); confirm they point to the correct paths"
      ],
      "qualityChecks": {
        "build": {
          "command": "yarn build",
          "required": true
        },
        "tests": {
          "command": "yarn test --roots='<rootDir>/src'",
          "required": true
        },
        "browserTests": {
          "command": "BROWSER=1 yarn test --roots='<rootDir>/src'",
          "required": true
        },
        "additionalChecks": [
          "yarn verify:lite-sync — must pass with no drift",
          "yarn check:lite-size — must pass under 7168 bytes gzipped"
        ]
      }
    },
    {
      "id": "story-6",
      "title": "Example apps: examples/lite-size-demos/",
      "approach": "general-purpose",
      "dependencies": ["story-3"],
      "files": {
        "create": [
          "examples/lite-size-demos/terser-only/entry.js",
          "examples/lite-size-demos/terser-only/build.sh",
          "examples/lite-size-demos/terser-only/README.md",
          "examples/lite-size-demos/webpack/entry.js",
          "examples/lite-size-demos/webpack/webpack.config.js",
          "examples/lite-size-demos/webpack/package.json",
          "examples/lite-size-demos/webpack/README.md",
          "examples/lite-size-demos/rollup/entry.js",
          "examples/lite-size-demos/rollup/rollup.config.js",
          "examples/lite-size-demos/rollup/package.json",
          "examples/lite-size-demos/rollup/README.md"
        ],
        "modify": [
          "package.json"
        ]
      },
      "implementationNotes": [
        "terser-only/entry.js: const { AvoInspector, AvoInspectorEnv } = require('avo-inspector/lite'); construct and call trackSchemaFromEvent",
        "terser-only/build.sh: esbuild entry.js --bundle --platform=browser --target=es5 --outfile=build/bundle.js && npx terser build/bundle.js --compress passes=2,unsafe=true,unsafe_comps=true --mangle --output build/bundle.min.js",
        "webpack/entry.js: import { AvoInspector, AvoInspectorEnv } from 'avo-inspector/lite'; construct and call trackSchemaFromEvent",
        "webpack/webpack.config.js: production mode; resolve avo-inspector to the parent package; UMD output",
        "rollup/entry.js: import { AvoInspector, AvoInspectorEnv } from 'avo-inspector/lite'; construct and call trackSchemaFromEvent",
        "rollup/rollup.config.js: uses @rollup/plugin-node-resolve and @rollup/plugin-commonjs",
        "rollup/package.json: declare rollup, @rollup/plugin-node-resolve, and @rollup/plugin-commonjs in devDependencies so the example is self-contained; user must run npm install inside the directory",
        "webpack/package.json: declare webpack and webpack-cli in devDependencies so the example is self-contained; user must run npm install inside the directory",
        "Each README.md: exact import, exact build command, expected sizes (~X KB placeholder until built), grep command showing no encryption code",
        "Add 'examples/lite-size-demos/' to package.json files array (alongside dist and bin)",
        "MERGE-CONFLICT WARNING: Story 6 and Story 3 both modify package.json. Although Story 6 depends on Story 3 (logically sequenced), if worked in parallel by different agents they will produce a merge conflict. Story 6's package.json edit must be applied only after Story 3's changes are fully committed."
      ],
      "qualityChecks": {
        "build": {
          "command": "yarn build",
          "required": true
        },
        "tests": {
          "command": "yarn test --roots='<rootDir>/src'",
          "required": true
        },
        "browserTests": {
          "command": "BROWSER=1 yarn test --roots='<rootDir>/src'",
          "required": true
        }
      }
    },
    {
      "id": "story-7",
      "title": "Final verification pass",
      "approach": "general-purpose",
      "dependencies": ["story-1", "story-2", "story-3", "story-4", "story-5", "story-6"],
      "files": {
        "create": [],
        "modify": []
      },
      "implementationNotes": [
        "Run all 24 spec acceptance criteria checks end-to-end",
        "yarn build — must succeed, produce dist/index.js and dist/lite/index.js",
        "grep -r 'AvoEncryption' dist/lite/ — no matches",
        "grep -r 'AvoEventSpecFetcher' dist/lite/ — no matches",
        "grep -r 'EventSpecCache' dist/lite/ — no matches",
        "grep -r 'noble' dist/lite/ — no matches",
        "grep -r 'safe-regex' dist/lite/ — no matches",
        "yarn test --roots='<rootDir>/src' — all tests pass",
        "BROWSER=1 yarn test --roots='<rootDir>/src' — all tests pass",
        "npm pack --dry-run | grep 'dist/lite' — includes dist/lite/index.js and dist/lite/index.d.ts",
        "yarn verify:lite-sync — no drift detected",
        "yarn check:lite-size — under 7168 bytes gzipped",
        "Verify static isolation test passes (batchSize isolation between full and lite)",
        "AC 21 — cd examples/lite-size-demos/terser-only && bash build.sh; verify build/bundle.min.js gzipped is under 7 KB",
        "AC 22 — cd examples/lite-size-demos/webpack && npm install && npx webpack; verify output gzipped is under 7 KB",
        "AC 23 — cd examples/lite-size-demos/rollup && npm install && npx rollup -c; verify output gzipped is under 7 KB",
        "Fix any issues found — no new files should be needed; corrections go in existing files from earlier stories"
      ],
      "qualityChecks": {
        "build": {
          "command": "yarn build",
          "required": true
        },
        "tests": {
          "command": "yarn test --roots='<rootDir>/src'",
          "required": true
        },
        "browserTests": {
          "command": "BROWSER=1 yarn test --roots='<rootDir>/src'",
          "required": true
        }
      }
    }
  ]
}
