diff --git a/.agent3-staging/tf-ARCHIVED.md b/.agent3-staging/tf-ARCHIVED.md deleted file mode 100644 index e69723f..0000000 --- a/.agent3-staging/tf-ARCHIVED.md +++ /dev/null @@ -1,26 +0,0 @@ -# ARCHIVED — Superseded by SAP-Transaction-Forensics - -This repository is **archived and no longer maintained** as of 2026-04-16. - -## Use this instead - -**[chrbailey/SAP-Transaction-Forensics](https://github.com/chrbailey/SAP-Transaction-Forensics)** — the successor repo contains everything in this repo plus: - -- 1,663 passing tests (70 test suites) -- 23 MCP tools for forensic analysis -- 7 evidence systems: Provenance Graph, Extraction Registry, Contradiction Engine (12-category), Schema Validator (438 fields), Reality-Gap Detector, Finding Lifecycle (8-state), Reviewer Handoff Packets -- 19 deterministic extraction paths (SAP O2C, FI/CO, P2P + Salesforce + NetSuite) -- Worker/Critic/Ralph pattern-discovery loop (24 Python tests) -- Field-level provenance with SHA-256 replay verification - -## What this repo was - -A static demo site built around the Salesforce/HERB dataset — 6 analysis tabs (Overview, CRM Pipeline, BPI Challenge, IDES Compliance, Client Cases, NLP Patterns) rendered at `transaction-forensics.vercel.app`. The NLP pipeline (TF-IDF + KMeans on 37,064 documents) lives in `analyze.py`. - -The live Vercel demo will continue to render because the static `public/` artifacts are preserved. No new features, fixes, or data updates will land here. - -## Why archived - -All forensic-engine development moved to the successor repo in Q1 2026. This repo's scope shrank to "static viewer for the HERB NLP demo," which the successor now absorbs. Keeping two repos diluted attention and led to README drift between them. - -For questions or historical context, the commit history is preserved in read-only form. diff --git a/.claude/context-checkpoint.md b/.claude/context-checkpoint.md deleted file mode 100644 index 4f97e94..0000000 --- a/.claude/context-checkpoint.md +++ /dev/null @@ -1,33 +0,0 @@ -# Context Checkpoint -Updated: 2026-03-26T00:15:00Z - -## Task -Add Salesforce adapter to SAP-Transaction-Forensics with cross-system ERP/CRM correlation, run analysis on synthetic data, update README, push to GitHub. - -## Status -Complete. Pushed to origin/main. - -## Decisions Made -- SFDC adapter lives in SAP-Transaction-Forensics repo (not separate project) -- Synthetic-first approach: generator with 10 planted patterns validates pipeline before real data -- Field mapper normalizes SFDC→SAP types (lossy by design, documented) -- Entity resolver: nameThreshold=0.3 (tightened from 0.6 after code review) -- Background agents fail on permissions — use foreground only for Write/Bash tasks - -## Files Modified -- 24 new files across mcp-server/src/adapters/sfdc/, mcp-server/src/cross-system/, pattern-engine/src/, synthetic-data/ -- README.md — rewritten for multi-system architecture, SFDC docs, 834 test count -- .gitignore — added sfdc_output, .firecrawl, crmarena exclusions -- pattern-engine/scripts/analyze_sfdc.py — forensic analysis script - -## Key Findings -- CRMArena/CRMArenaPro on HuggingFace are benchmarks (Q&A), not raw data dumps -- Kaggle `innocentmfa/crm-sales-opportunities` has real CRM data (accounts.csv, sales_pipeline.csv) — needs kaggle CLI auth -- HERB dataset is enterprise communications, not pipeline data — useful for NLP layer only -- Pre-existing test failure: conformance.test.ts "should list all models" expects 4, gets 7 (on main) - -## Next Steps -1. Download Kaggle CRM dataset (need `pip install kaggle` + auth) and write CSV→JSON converter -2. Wire MCP tool registrations for cross-system tools (correlate_systems, get_unified_log, analyze_cross_system_gaps) -3. Phase 2: Live Salesforce REST API client with OAuth2 -4. Consider: integrate Tech41 NLP pipeline (HERB communications) alongside structured SFDC adapter diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..395b498 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,45 @@ +version: 2 +updates: + # MCP server (TypeScript) + - package-ecosystem: "npm" + directory: "/mcp-server" + schedule: + interval: "weekly" + open-pull-requests-limit: 5 + groups: + dev-dependencies: + dependency-type: "development" + + # Web viewer + - package-ecosystem: "npm" + directory: "/viewer" + schedule: + interval: "weekly" + open-pull-requests-limit: 5 + + # Pattern engine (Python) + - package-ecosystem: "pip" + directory: "/pattern-engine" + schedule: + interval: "weekly" + open-pull-requests-limit: 5 + + # GitHub Actions + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + + # Container base images + - package-ecosystem: "docker" + directory: "/mcp-server" + schedule: + interval: "weekly" + - package-ecosystem: "docker" + directory: "/pattern-engine" + schedule: + interval: "weekly" + - package-ecosystem: "docker" + directory: "/viewer" + schedule: + interval: "weekly" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f8d1973..4fa8de4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -225,6 +225,60 @@ jobs: - name: Run prediction demo run: npx tsx ../demos/predict_outcome_demo.ts + # ============================================================================ + # Security & Supply Chain (non-blocking for now — reports only) + # ============================================================================ + security: + name: Security & SBOM + runs-on: ubuntu-latest + # Do not fail the pipeline yet: surface dependency advisories and produce + # SBOMs while the flagged issues are triaged. Flip continue-on-error to + # false (and add audit-level gating) once the backlog is clean. + continue-on-error: true + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: npm audit (mcp-server, production deps) + working-directory: mcp-server + run: npm audit --omit=dev || true + + - name: npm audit (viewer, production deps) + working-directory: viewer + run: npm audit --omit=dev || true + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.11' + + - name: pip-audit (pattern-engine) + run: | + python -m pip install --upgrade pip pip-audit + pip-audit -r pattern-engine/requirements.txt || true + + - name: Generate SBOMs (CycloneDX) + run: | + # Node SBOMs from the committed lockfiles. + (cd mcp-server && npm ci --ignore-scripts && npm sbom --sbom-format cyclonedx > ../mcp-server-sbom.cdx.json) || true + (cd viewer && npm ci --ignore-scripts && npm sbom --sbom-format cyclonedx > ../viewer-sbom.cdx.json) || true + # Python SBOM. + python -m pip install cyclonedx-bom || true + cyclonedx-py requirements pattern-engine/requirements.txt -o pattern-engine-sbom.cdx.json || true + + - name: Upload SBOM artifacts + uses: actions/upload-artifact@v4 + with: + name: sboms + path: '*-sbom.cdx.json' + if-no-files-found: warn + # ============================================================================ # Build Artifacts # ============================================================================ @@ -267,5 +321,5 @@ jobs: echo "| Pattern Engine | ✅ Tests Passed |" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "### Test Results" >> $GITHUB_STEP_SUMMARY - echo "- MCP Server: 605+ tests" >> $GITHUB_STEP_SUMMARY + echo "- MCP Server: see the test job output for the current count" >> $GITHUB_STEP_SUMMARY echo "- Pattern Engine: See pytest output" >> $GITHUB_STEP_SUMMARY diff --git a/.gitignore b/.gitignore index 8032436..f70f45c 100644 --- a/.gitignore +++ b/.gitignore @@ -26,7 +26,9 @@ logs/ # Environment .env -.env.local +.env.* +!.env.*.example +.env.rfc # Coverage coverage/ @@ -45,7 +47,9 @@ output/*.svg output/*.png output/datasphere_analysis/ output/e2e_test/ +output/*.md pattern-engine/csv_test_output/ +pattern-engine/test_output/ synthetic-data/external_data/ # Downloaded datasets (keep .gitkeep) diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..209e3ef --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +20 diff --git a/.python-version b/.python-version new file mode 100644 index 0000000..2c07333 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.11 diff --git a/CLAUDE.md b/CLAUDE.md index 8ef463a..f209ca0 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -46,22 +46,26 @@ cd pattern-engine && pytest tests/ -v transaction-forensics/ ├── mcp-server/ # MCP server with TypeScript │ ├── src/ -│ │ ├── index.ts # Entry point -│ │ ├── adapters/ # SAP, SFDC, NetSuite, SALT, BPI, CSV adapters +│ │ ├── index.ts # Entry point (registers 27 tools; see note below) +│ │ ├── adapters/ # SAP (ECC RFC + S/4 OData stub), SFDC, SALT, BPI, CSV, synthetic │ │ ├── conformance/ # Process conformance checking -│ │ ├── evidence/ # Provenance graph, extraction registry +│ │ ├── provenance/ # Provenance graph + replay hashing +│ │ ├── extraction-registry/# Named extraction paths (incl. NetSuite SuiteQL metadata) │ │ ├── contradiction/ # Cross-system contradiction engine -│ │ ├── schema/ # Schema validator (IDES reference) +│ │ ├── cross-system/ # Entity resolution across systems +│ │ ├── schema-validator/ # Schema validator (IDES reference) │ │ ├── reality-gap/ # Three-way gap analysis │ │ ├── finding-lifecycle/ # 8-state finding manager + SQLite │ │ ├── handoff/ # Reviewer handoff packet generator -│ │ ├── fi-co/ # FI/CO forensic analysis tools │ │ ├── governance/ # PromptSpeak integration │ │ ├── llm/ # Natural language interface +│ │ ├── logging/ # Audit logger │ │ ├── ocel/ # OCEL 2.0 export -│ │ ├── policies/ # Business rules +│ │ ├── policies/ # Business rules / access limits │ │ ├── prediction/ # ML predictions -│ │ ├── tools/ # MCP tool definitions +│ │ ├── reports/ # FI/CO report generation +│ │ ├── tools/ # MCP tool definitions (FI/CO tools live here as analyze-*.ts) +│ │ ├── types/ # Shared TypeScript types (incl. fi-co types) │ │ └── visualization/ # Process maps ├── pattern-engine/ # Pattern discovery engine (Python) │ ├── scripts/ # analyze_sfdc.py, etc. @@ -120,6 +124,10 @@ transaction-forensics/ | `generate_fi_assessment` | FI/CO risk assessment report | ### Evidence Infrastructure Tools +> Note: these nine tools are implemented and unit-tested but are **not yet +> registered** on the MCP server (`src/tools/index.ts` exposes 18 analysis + 9 +> governance = 27 tools). Wiring them into the server is tracked in +> [docs/GOVERNMENT-READINESS-REVIEW.md](docs/GOVERNMENT-READINESS-REVIEW.md). | Tool | Purpose | |---|---| | `query_provenance` | Trace evidence chain for a finding | @@ -152,14 +160,15 @@ transaction-forensics/ ## Environment Variables ```bash # LLM providers (choose one) -OLLAMA_BASE_URL=http://localhost:11434 # Local, private +OLLAMA_HOST=http://localhost:11434 # Local, private (default provider) OPENAI_API_KEY=sk-... # Cloud option ANTHROPIC_API_KEY=sk-ant-... # Cloud option -# SAP RFC (optional) -SAP_HOST=... -SAP_SYSNR=... -SAP_CLIENT=... -SAP_USER=... -SAP_PASSWORD=... +# SAP RFC (optional) — see .env.rfc.example for the full list +SAP_RFC_ASHOST=... +SAP_RFC_SYSNR=00 +SAP_RFC_CLIENT=100 +SAP_RFC_USER=... +SAP_RFC_PASSWD=... +SAP_RFC_LANG=EN ``` diff --git a/SECURITY.md b/SECURITY.md index 6b8e973..d84d8b3 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -12,10 +12,20 @@ Transaction Forensics is designed for enterprise security requirements: - **Read-only access** - No write operations to SAP - **Local by default** - Cloud LLM providers and SaaS adapters are opt-in -- **No telemetry** - No phone-home, no usage tracking -- **PII protection** - Automatic redaction enabled by default -- **Audit logging** - Complete request/response logging -- **Minimal permissions** - Principle of least privilege +- **No telemetry** - No phone-home, no usage tracking (verified: the only + outbound endpoints in the code are the opt-in LLM and SaaS adapters) +- **PII protection** - Redaction available in the Python pattern engine's + shareable-output mode. Note: the MCP server's SAP/SFDC data tools return raw + field text and are **not** redacted; treat all tool output as sensitive. +- **Audit logging** - Tool calls are logged with parameters and result + **metadata** (row counts, duration, truncation) — not response bodies. +- **Minimal permissions** - Principle of least privilege on the SAP side + +> **Authentication:** the product itself does not yet provide user +> authentication or authorization. The MCP server runs over a single-user stdio +> transport and the web viewer ships without auth or TLS. Deploy both behind +> your own network controls / reverse proxy. See the roadmap in +> [docs/GOVERNMENT-READINESS-REVIEW.md](docs/GOVERNMENT-READINESS-REVIEW.md). --- @@ -50,7 +60,7 @@ Transaction Forensics is designed for enterprise security requirements: || | +-------------------+ | HTTP | | (4) | || || | | Browser |<--------->| +------------------------+ | || || | | (localhost:8080) | | (5) | | Web Viewer | | || -|| | +-------------------+ | | | (localhost only) | | || +|| | +-------------------+ | | | (no built-in auth) | | || || | | | +------------------------+ | || || +---------------------------+ +-------------------------------+ || || || @@ -69,7 +79,13 @@ Data Flow Steps: (2) Internal processing - text extraction, normalization (3) Pattern analysis and redaction (4) Results stored locally -(5) Browser access via localhost only +(5) Browser access to the viewer. Note: the viewer binds all interfaces and + has no built-in authentication or TLS — restrict it to localhost or place + it behind an authenticating reverse proxy on deployment. + +Note: the MCP server communicates over a stdio transport (not an HTTP port); +the pattern engine and MCP tools are invoked in-process by the MCP host, not +over a network socket. ``` --- @@ -91,13 +107,26 @@ Data Flow Steps: | KNA1 | Customer Master | Customer attributes | High | | MARA | Material Master | Material attributes | Low | +### FI/CO Tables (via CSV import or Read-Only BAPIs) + +The FI/CO forensic tools (`analyze_journal_entries`, `analyze_sod`, +`analyze_gl_balances`, `get_fi_document`, `generate_fi_assessment`) read +financial-accounting data when an FI/CO source is provided: + +| Table | Description | Sensitivity | +|-------|-------------|-------------| +| BKPF / BSEG | Accounting document header / line items | High | +| BSAD | Cleared customer items | Medium | +| SKA1 / SKAT | G/L account master / texts | Low | +| T001 | Company codes | Low | +| CSKS / COEP | Cost centers / CO line items | Medium | + ### Data NOT Accessed -- FI/CO tables (financial accounting) - HR/HCM tables (employee data) - Pricing conditions (KONV, A-tables) - Credit management (KNKK) -- Bank details (BNKA, KNBK) +- Bank details (BNKA, KNBK, LFBK) — no vendor-bank reads today - Custom Z-tables (unless explicitly configured) ### BAPIs Used @@ -171,8 +200,8 @@ Required connections depend on the selected adapters and LLM provider: | Source | Destination | Port | Protocol | Purpose | |--------|-------------|------|----------|---------| | MCP Server | SAP ECC | 33XX | RFC | SAP data access | -| Browser | Web Viewer | 8080 | HTTP | Results viewing | -| Pattern Engine | MCP Server | 3000 | HTTP | Tool calls | +| Browser | Web Viewer | 8080 | HTTP | Results viewing (bind to localhost / proxy) | +| MCP host | MCP Server | n/a | stdio | Tool calls (in-process, no network port) | | MCP Server | Salesforce/NetSuite | 443 | HTTPS | Optional SaaS adapters | | MCP Server | OpenAI/Anthropic | 443 | HTTPS | Optional cloud LLM | @@ -297,14 +326,15 @@ Every tool call is logged with: "row_count": 47, "execution_ms": 234, "truncated": false - }, - "user_context": { - "session_id": "abc123", - "client_ip": "10.0.0.50" } } ``` +> Note: the audit log does not currently capture a user/session identity or +> client IP — the MCP server runs over a single-user stdio transport with no +> caller identity. Per-user attribution is on the roadmap and is a prerequisite +> for a full chain-of-custody story. + ### What Is NOT Logged - Actual document content (only metadata) @@ -314,10 +344,13 @@ Every tool call is logged with: ### Log Retention -Logs are stored locally in `./output/logs/`: -- Default retention: 90 days -- Configurable via environment variable +Logs are written locally by winston with **size-based rotation** (default 5 +files × 10 MB); there is no time-based retention window today. Set the log +directory via the `LOG_DIR` environment variable. - No automatic upload or external shipping +- Note: the audit log is a plaintext file with no integrity protection + (hash-chaining / signing) yet — see the roadmap for the tamper-evident logging + work required before it can serve as evidence. --- @@ -354,6 +387,11 @@ The RFC user should have: ## Compliance Considerations +> The tables below describe how the product can **support a customer's own +> compliance program** — they are not claims of independently audited or +> attested product controls. No SOC 2 report or third-party certification +> exists for this software today. + ### GDPR | Requirement | Implementation | @@ -363,34 +401,34 @@ The RFC user should have: | Storage limitation | Local only, configurable retention | | Right to erasure | Delete output directory | | Data portability | JSON output format | -| Privacy by design | Redaction enabled by default | +| Privacy by design | Redaction available in the pattern engine's shareable-output mode (raw MCP tool output is not redacted) | ### SOC 2 -| Control | Implementation | +| Control | How the product supports it | |---------|----------------| -| Access control | SAP authorization, no shared accounts | -| Audit logging | Complete request logging | -| Data encryption | Use TLS for RFC (SNC) | +| Access control | Enforced on the **SAP side** via display-only authorizations. The product itself has no user auth yet — deploy behind your controls. | +| Audit logging | Tool-call metadata logging (parameters, row counts, timing) — not response bodies; no tamper-evidence yet | +| Data encryption | Deploy RFC with SNC and the viewer behind TLS — **not** currently configured by the product (no SNC parameters in the RFC client today) | | Change management | Docker image versioning | | Incident response | Local logs for investigation | ### HIPAA (if applicable) -| Safeguard | Implementation | +| Safeguard | How the product supports it | |-----------|----------------| -| Access controls | SAP authorization | -| Audit controls | Complete logging | -| Transmission security | SNC for RFC | +| Access controls | SAP authorization (product has no user auth of its own yet) | +| Audit controls | Tool-call metadata logging | +| Transmission security | SNC for RFC — configure at the OS/SAP layer; not set by the product today | | No PHI processing | Verify no healthcare data in SD texts | ### PCI DSS (if applicable) -| Requirement | Implementation | +| Requirement | How the product supports it | |-------------|----------------| -| No card data storage | Credit card patterns redacted | +| No card data storage | Credit-card patterns redacted in the pattern engine's shareable mode (not in raw MCP tool output) | | Access restriction | SAP authorization | -| Audit trails | Complete logging | +| Audit trails | Tool-call metadata logging | | Network security | Outbound access limited to configured providers | --- @@ -440,9 +478,12 @@ Before deploying Transaction Forensics: - [ ] Create dedicated RFC user with minimal permissions - [ ] Test authorization with SU53 after failed access -- [ ] Enable SNC (Secure Network Communications) for RFC +- [ ] Enable SNC (Secure Network Communications) for RFC at the SAP/OS layer + (the product's RFC client does not set SNC parameters itself) - [ ] Review SAP authorization trace (ST01) -- [ ] Configure log retention policy +- [ ] Restrict the web viewer to localhost or place it behind an + authenticating, TLS-terminating reverse proxy (no built-in auth/TLS) +- [ ] Set `LOG_DIR` and manage log rotation/retention at the OS layer - [ ] Restrict outbound access to explicitly configured providers - [ ] Document data classification of output - [ ] Establish output file handling procedures diff --git a/agent1-work/check_yaml.py b/agent1-work/check_yaml.py deleted file mode 100644 index 6ec2c5c..0000000 --- a/agent1-work/check_yaml.py +++ /dev/null @@ -1,17 +0,0 @@ -import base64, subprocess -result = subprocess.run( - ['gh', 'api', 'repos/chrbailey/restaurant-scheduler/contents/.github/workflows/release.yml', '--jq', '.content'], - capture_output=True, text=True, -) -content = base64.b64decode(result.stdout).decode('utf-8') -lines = content.split('\n') -for i, line in enumerate(lines[:25], 1): - print(f'{i:3}: {line!r}') -print('---') -print(f'Total lines: {len(lines)}') -print(f'Total bytes: {len(content)}') -# Look for name: Release at start -if content.startswith('name: Release'): - print('Starts correctly with name: Release') -else: - print(f'Starts with: {content[:50]!r}') diff --git a/agent1-work/dossier-CHANGELOG.md b/agent1-work/dossier-CHANGELOG.md deleted file mode 100644 index a17a914..0000000 --- a/agent1-work/dossier-CHANGELOG.md +++ /dev/null @@ -1,74 +0,0 @@ -# Changelog - -All notable changes to this project are recorded here. Format loosely follows -[Keep a Changelog](https://keepachangelog.com/en/1.1.0/). Versioning is -[Semantic Versioning](https://semver.org/). - -The default branch is `corrections/calibrated-v1`. That name records that the -current state of the tree is a corrected, calibrated re-base of earlier work -rather than a clean slate. - -## [Unreleased] - -### Added -- `CHANGELOG.md` (this file). - -## [0.1.0-corrections] — 2026-04-20 - -### Added -- **7-phase SaaS due diligence pipeline** orchestrated by Ralph Loop: - Discovery, Market, Technical, Claims, Academic, Valuation, Report. Driven - by prompt files in `prompts/p{N}-*.md` and templates in `templates/`. -- **Phase 4 shadow prediction market** methodology: 11 internal signal source - types (Glassdoor, Blind, Reddit, HN, LinkedIn, layoff trackers, arXiv, - Twitter/X, job boards, Product Hunt, review sites). 3+ independent sources - required per quantitative claim; the cross-source spread is the confidence - interval. -- **Signal curation loop** (`contracts/signal-curation.json`, - `contracts/signal-monitor.json`): contract-driven research loop with - trusted source universe (Karpathy, Amodei, Altman, Hassabis, Sutskever, - etc.), trust weights, and freshness horizons. Run via `dspy/__main__.py` - with `scripts/run_loop.py` harness. -- **DSPy compilation pipeline** (`dspy/`): signatures, modules, loaders, - metrics, compiler, export. Uses `dspy-ai` under the hood and a custom - `ClaudeAgentLM` backend so LLM calls go through the local Claude Code - harness rather than a direct Anthropic API client. -- **Circuit breaker** (`scripts/circuit_breaker.py` and related) for - safe repeated LLM invocations — halts the loop on consecutive failures. -- **Evidence store** (`scripts/evidence_store.py` and related): append-only - evidence capture with insert/query/promotion/signal extraction tested - separately. -- **Output viewer** (`viewer/`): static HTML viewer for generated reports. -- Helper scripts (Python 3.9+ compat): `whois_lookup.py`, `arxiv_search.py`. -- `CLAUDE.md` project rules, `ARCHITECTURE.md` design doc, `llm.md` agent - integration guide. -- `SECURITY.md` with threat model: read-only research, no authenticated - writes against third parties, public sources only, no Anthropic API keys - held by the project (all LLM calls go through the host Claude Code - harness). -- `CONTRIBUTING.md` with scope constraints: no API-wrapping CLI replacement - of the sub-agent architecture, no required paid data sources, no - softening of Phase 4 methodology, no scoring of raw evidence captures. -- GitHub Actions `tests.yml` CI matrix across Python 3.10 / 3.11 / 3.12, - triggered on `main` and all `corrections/**` branches. - -### Tests -- **330 pytest tests passing** across 15 test files (verified from the - 2026-04-20 CI run on `corrections/calibrated-v1`, commit 6638f2c). Test - areas: circuit breaker, contract integration, DSPy compile/export/loader, - evidence store (guards, insert/query, promotion, signals), metrics, - modules, signatures, LM backend, integration. - -### Known Limitations -- No browser automation — WebSearch / WebFetch only. Some target sites - (LinkedIn, Glassdoor) restrict what the pipeline can retrieve. -- No financial data APIs — SaaS metrics are estimated from public signals, - not Crunchbase / PitchBook / S&P. -- No deep static analysis of target code — repos are analyzed via `gh` - CLI and file inspection only. -- Single-domain runs; no side-by-side comparison mode. -- Running against a competitor with a corporate-identity `gh` token exposes - that identity to the target in GitHub API logs — see `SECURITY.md`. - -[Unreleased]: https://github.com/chrbailey/dossier/compare/v0.1.0-corrections...HEAD -[0.1.0-corrections]: https://github.com/chrbailey/dossier/tree/corrections/calibrated-v1 diff --git a/agent1-work/dossier-README.md b/agent1-work/dossier-README.md deleted file mode 100644 index 236c9c0..0000000 --- a/agent1-work/dossier-README.md +++ /dev/null @@ -1,300 +0,0 @@ -# Dossier — Automated SaaS Due Diligence + Signal Curation - -[![tests](https://github.com/chrbailey/dossier/actions/workflows/tests.yml/badge.svg)](https://github.com/chrbailey/dossier/actions/workflows/tests.yml) -[![Python](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/) -[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT) - -> **Status: `corrections/calibrated-v1` branch is the default.** This repo was re-calibrated from earlier work — the branch name records that. 330 pytest tests passing on CI. Treat as v0.1 — useful, opinionated, single-author. See [CHANGELOG.md](CHANGELOG.md). - -**What it does:** Two Claude Code-native research loops that share the same architectural pattern (prompt-as-program, PROGRESS.md as state, DAG of sub-agents): - -1. **SaaS due diligence pipeline** — given a domain, produces a 7-phase dossier: discovery, market, technical, claims vs reality, academic footprint, replication cost, unified report. -2. **Signal curation loop** — given a contract (`contracts/*.json`), continuously curates the most important voices, signals, and absences on a topic. Uses DSPy for compiled prompt programs under `dspy/`. - -**When to use the due diligence pipeline:** You are evaluating a SaaS company for acquisition, investment, partnership, or competitive intelligence. You want more than a landing page review but less than a $200K consulting engagement. - -**When to use the signal curation loop:** You want an agent that monitors a named source universe (Karpathy, Amodei, Altman, Hassabis, etc.) and reports on pattern shifts and meaningful silences, on a schedule. - -**How both work:** Claude Code is the execution engine. Sub-agents have direct access to WebSearch, WebFetch, `gh` CLI, file I/O. The "program" is a set of prompt files + contract files. The "database" is `PROGRESS.md` or an append-only evidence store. The "scheduler" is Ralph Loop (for dossier) or a contract-driven loop harness (for signal curation). - -## What This Is NOT - -- **Not a hosted service.** You clone the repo, configure `target.env` (for dossier) or a `contracts/*.json` (for signal), and run it locally against your own Claude Code harness. -- **Not a browser automation tool.** WebSearch + WebFetch only. Sites that block those (LinkedIn, Glassdoor) will have partial coverage. -- **Not a financial data provider.** The valuation phase estimates from public signals only — no Crunchbase, PitchBook, or S&P integrations. -- **Not a replacement for a human analyst.** The output is a starting point for human judgment, not a verdict. -- **Not API-key-hungry.** All LLM calls go through your local Claude Code harness — Dossier does not hold or use an Anthropic API key directly. - ---- - -## Quick Start — Due Diligence Pipeline - -```bash -git clone https://github.com/chrbailey/dossier.git -cd dossier - -# 1. Set target -echo "DOMAIN=example.com" > target.env - -# 2. Install helper dependencies (one-time) -python3 -m venv scripts/.venv -scripts/.venv/bin/pip install -r scripts/requirements.txt - -# 3. Run the pipeline (Ralph Loop, inside Claude Code) -# /ralph-loop --max-iterations 20 --completion-promise "DOSSIER_COMPLETE" -# (paste contents of ralph-prompt.md when prompted) - -# 4. Read results -cat output/example.com/executive-summary.md -cat output/example.com/07-report.md -``` - -## Quick Start — Signal Curation Loop - -```bash -# 1. Pick a contract -ls contracts/ # signal-curation.json, signal-monitor.json - -# 2. Install DSPy pipeline deps -pip install -r dspy/requirements.txt - -# 3. Run the loop (inside Claude Code) -# Use /dossier-loop or run the harness directly: -python -m dspy.__main__ contracts/signal-curation.json -``` - ---- - -## What You Get — Due Diligence - -A complete dossier in `output/{domain}/`: - -| File | Contents | -|------|----------| -| `executive-summary.md` | 2-page overview: strengths, risks, recommendation | -| `07-report.md` | Full PRD-format report with all sections | -| `01-discovery.md` | Company identity, digital footprint, tech signals | -| `02-market.md` | TAM/SAM/SOM, competitors, SWOT, positioning matrix | -| `03-technical.md` | GitHub analysis, architecture, code quality, dependencies | -| `04-claims.md` | Marketing vs reality — with shadow prediction market | -| `05-academic.md` | Papers, patents, open-source alternatives | -| `06-valuation.md` | SaaS metrics, replication cost, agent swarm build plan | -| `raw/*.json` | WHOIS, website content, GitHub repos, arXiv papers | - ---- - -## The 7 Phases - -``` -P1 Discovery ──┬──→ P2 Market ────────┐ - ├──→ P3 Technical ──┐ │ - └──→ P5 Academic │ │ - ▼ │ - P4 Claims (P1+P3) ──┤ │ - ▼ ▼ - P6 Valuation (all) ────┤ - ▼ - P7 Report (all) → DONE -``` - -| Phase | What It Does | Tools Used | -|-------|-------------|------------| -| **P1 Discovery** | Domain → company identity, digital footprint | WebSearch, WebFetch, WHOIS script, dig | -| **P2 Market** | Market size, competitors, SWOT, Gartner-style positioning | WebSearch, WebFetch | -| **P3 Technical** | GitHub org analysis, architecture, dependencies, quality signals | `gh` CLI, WebFetch | -| **P4 Claims** | Marketing claims vs evidence + shadow prediction market from internal signals | WebSearch (11 source types), prior phase outputs | -| **P5 Academic** | arXiv papers, patents, open-source alternatives | arXiv script, `gh search`, WebSearch | -| **P6 Valuation** | SaaS metrics, replication assessment, agent swarm build plan | All prior phases | -| **P7 Report** | Unified PRD + executive summary + confidence matrix | All prior phases | - -### Phase 4: The Shadow Prediction Market - -The most differentiated phase. Instead of taking marketing claims at face value, P4 triangulates **internal signals** from 11 source types — Glassdoor, Blind, Reddit, HN, LinkedIn, layoff trackers, arXiv, Twitter/X, job boards, Product Hunt, and review sites. - -The core method: collect 3+ independent data points for each quantitative claim. The **spread** across sources becomes the confidence interval. When the company's claim falls outside the triangulated range, that's a material gap. When employee signals contradict marketing, the employee signals get higher weight. - -Output includes an "AI Reality Score" (1-5): is their AI genuine research-grade ML, or a rules engine with a marketing department? - ---- - -## Signal Curation Loop - -The `contracts/` directory defines contract-driven research loops. `signal-curation.json` names a source universe (Karpathy, Amodei, Altman, Hassabis, Sutskever, etc.) with tier, trust weight, freshness horizon, and domains. The loop monitors those sources for signal shifts, emerging patterns, and meaningful silences. - -Under `dspy/`, a compiled DSPy pipeline handles the LLM calls. A custom `ClaudeAgentLM` adapter (`dspy/lm.py`) routes those calls through the host Claude Code harness instead of calling the Anthropic API directly. - -`contracts/schema.md` documents the contract format. - ---- - -## Architecture - -### Why Claude Code Native? - -Traditional approach: build a Python CLI that wraps Claude API → manage keys, handle rate limits, parse responses, maintain code. - -This approach: Claude Code **is** the execution engine. Sub-agents have direct access to WebSearch, WebFetch, `gh` CLI, file I/O. The "program" is prompt files + contract files. The "database" is `PROGRESS.md` or the evidence store. The "scheduler" is Ralph Loop or the contract loop harness. - -**Result:** ~120 LOC of hand-written Python helper scripts + a compact DSPy pipeline + ~1,300 lines of structured prompts. Full SaaS due diligence and signal curation pipelines, with 330 passing tests. - -### State Machine - -``` -target.env → PROGRESS.md (state) → ralph-prompt.md (scheduler) - ↕ ↕ - output/{domain}/ prompts/p{N}-*.md - (phase outputs) (sub-agent instructions) -``` - -Ralph Loop reads `PROGRESS.md` each iteration, identifies unblocked phases, dispatches sub-agents, updates state, and repeats until all phases complete or max iterations reached. - -### Helper Scripts - -Only a small set of Python scripts — for tasks Claude Code can't do natively: - -| Script | Purpose | Input → Output | -|--------|---------|---------------| -| `scripts/whois_lookup.py` | WHOIS records | domain → JSON | -| `scripts/arxiv_search.py` | Academic papers | query → JSON array | -| `scripts/circuit_breaker.py` | Halt loop on consecutive LLM failures | — | -| `scripts/evidence_store.py` | Append-only evidence store with guards | — | - -### DSPy Pipeline - -`dspy/` contains a compiled DSPy program used by the signal curation loop: -`signatures.py` (I/O shapes), `modules.py` (composable units), `loader.py` -(dataset ingestion), `metrics.py` (scoring), `compile.py` (program -compilation), `export.py` (compiled-program export), `lm.py` (ClaudeAgentLM -backend), `__main__.py` (entry point). The `tests/test_*` files cover each -of these components plus integration. - ---- - -## Testing - -```bash -pip install -r scripts/requirements.txt -pip install -r dspy/requirements.txt -pip install pytest pytest-asyncio - -python -m pytest tests/ -v -``` - -Current suite: **330 tests passing** on CI (Python 3.10 / 3.11 / 3.12). Test areas include circuit breaker, contract integration, DSPy compile/export/loader/signatures/modules, evidence store (guards, insert/query, promotion, signal extraction), metrics, LM backend, and integration tests. - ---- - -## For Agent Builders - -### Patterns You Can Reuse - -1. **Prompt-as-program:** Each phase is a markdown file that fully specifies a sub-agent's behavior. No code generation framework needed — the prompts ARE the code. - -2. **PROGRESS.md as state machine:** A human-readable markdown file tracks completion state. Any agent can read it, any agent can update it. No database, no API. - -3. **DAG via dependency rules:** Phase dependencies are declared in `ralph-prompt.md` as simple rules (`P1 + P3 → unlocks P4`). Ralph Loop interprets these each iteration. Adding a phase means adding one rule. - -4. **Signal triangulation:** The Phase 4 methodology — collect 3+ independent sources, derive confidence from convergence — is reusable for any verification task. - -5. **Materiality tiers:** CRITICAL / NOTABLE / MINOR classification with explicit trigger conditions. Prevents false alarms from minor discrepancies. - -6. **Contract-driven research loops:** `contracts/*.json` declare source universe, trust weights, freshness horizons, and loop phases. The same harness runs different research contracts. - -### Extending Dossier - -**Add a new phase:** -1. Create `prompts/p{N}-{name}.md` with goal, steps, output format -2. Add dependency rule to `ralph-prompt.md` -3. Add to `templates/progress-template.md` - -**Add a new data source:** -1. If it needs a library: add script to `scripts/`, update `requirements.txt` -2. If WebSearch/WebFetch suffices: just add instructions to the relevant phase prompt - -**Run against a different domain:** -1. Edit `target.env` -2. Run Ralph Loop — each domain gets its own `output/{domain}/` directory - -**Write a new research contract:** -1. See `contracts/schema.md` for the format -2. Add JSON under `contracts/` -3. Point the loop harness at the contract file - ---- - -## Project Structure - -``` -dossier/ -├── README.md / ARCHITECTURE.md / CLAUDE.md / llm.md / SECURITY.md -├── CONTRIBUTING.md / CHANGELOG.md / LICENSE -├── target.env # DOMAIN=example.com -├── ralph-prompt.md # Ralph Loop orchestration prompt -├── pyproject.toml -│ -├── scripts/ # Python helpers (JSON stdout) -│ ├── whois_lookup.py -│ ├── arxiv_search.py -│ ├── circuit_breaker.py -│ ├── evidence_store.py -│ └── requirements.txt -│ -├── prompts/ # Sub-agent phase instructions -│ ├── p1-discovery.md … p7-report.md -│ -├── templates/ # Report structure templates -│ ├── progress-template.md -│ ├── prd-template.md -│ ├── swot-template.md -│ └── magic-quadrant-template.md -│ -├── contracts/ # Research loop contracts -│ ├── schema.md -│ ├── signal-curation.json -│ └── signal-monitor.json -│ -├── dspy/ # Compiled DSPy pipeline -│ ├── signatures.py / modules.py / loader.py -│ ├── metrics.py / compile.py / export.py -│ ├── lm.py (ClaudeAgentLM) / __main__.py -│ └── requirements.txt -│ -├── loop/ # Generic Ralph-loop template -│ ├── ralph-prompt-loop.md -│ ├── prompts/ / templates/ -│ -├── viewer/ # Static HTML report viewer -│ -├── tests/ # 330 pytest tests -│ -└── output/ # Generated reports (gitignored) - └── {domain}/ - ├── PROGRESS.md - ├── 01-discovery.md … 07-report.md - ├── executive-summary.md - └── raw/*.json -``` - ---- - -## Limitations (v0.1) - -- **No browser automation** — WebSearch/WebFetch only. Some sites (LinkedIn, Glassdoor) may limit what's accessible. -- **No financial APIs** — SaaS metrics are estimated from public signals, not Crunchbase/PitchBook data. -- **No deep code analysis** — GitHub repos are analyzed via `gh` CLI and file inspection, not cloned + run through static analysis. -- **Single domain per run** — no side-by-side comparison mode. -- **`gh` token identity exposure** — running Dossier against a competitor reveals your `gh`-authenticated identity in their API logs. - -See the V2 roadmap in `ARCHITECTURE.md`. - ---- - -## Inspiration - -The idea for automated SaaS due diligence was sparked by [Charmaine Wilson](https://www.linkedin.com/in/charmaine-wilson-deloitte) (Deloitte Consulting Principal) and [Ayo Odusote](https://www.linkedin.com/in/ayoodusote/) (Deloitte Principal, Software & Platforms Leader) in the context of Taryn Plumb's CIO.com article ["SaaS isn't dead, the market is just becoming more hybrid"](https://www.cio.com/article/4131904/saas-isnt-dead-the-market-is-just-becoming-more-hybrid.html). Their insight — that enterprises will balance traditional SaaS with AI-native alternatives, and that a new governance layer will emerge to orchestrate AI agents — is exactly the landscape where automated due diligence becomes essential. - ---- - -## License - -MIT diff --git a/agent1-work/gh_put.py b/agent1-work/gh_put.py deleted file mode 100644 index 08ce3ed..0000000 --- a/agent1-work/gh_put.py +++ /dev/null @@ -1,80 +0,0 @@ -#!/usr/bin/env python3 -"""Helper: PUT a file to GitHub via gh api with proper base64 encoding. - -Usage: gh_put.py - -Gets current sha if present, then PUTs the content. Uses base64 with no newlines. -""" -from __future__ import annotations - -import base64 -import json -import subprocess -import sys -from pathlib import Path - - -def gh_api(args: list[str], check: bool = True) -> tuple[int, str, str]: - proc = subprocess.run( - ["gh", "api"] + args, - capture_output=True, - text=True, - ) - if check and proc.returncode != 0: - sys.stderr.write(f"gh api failed: {proc.stderr}\n") - return proc.returncode, proc.stdout, proc.stderr - - -def get_sha(repo: str, path: str, branch: str) -> str | None: - rc, out, _ = gh_api( - ["-H", "Accept: application/vnd.github+json", f"repos/{repo}/contents/{path}?ref={branch}"], - check=False, - ) - if rc != 0: - return None - try: - data = json.loads(out) - return data.get("sha") - except json.JSONDecodeError: - return None - - -def put_file(repo: str, path: str, branch: str, message: str, local_file: str) -> int: - content = Path(local_file).read_bytes() - b64 = base64.b64encode(content).decode("ascii") - sha = get_sha(repo, path, branch) - - payload = { - "message": message, - "content": b64, - "branch": branch, - } - if sha: - payload["sha"] = sha - - # Use input-file approach via stdin to avoid any shell quoting issues - proc = subprocess.run( - [ - "gh", "api", "--method", "PUT", - "-H", "Accept: application/vnd.github+json", - f"repos/{repo}/contents/{path}", - "--input", "-", - ], - input=json.dumps(payload), - capture_output=True, - text=True, - ) - if proc.returncode != 0: - sys.stderr.write(f"PUT failed for {repo}/{path}:\n{proc.stderr}\n") - return proc.returncode - resp = json.loads(proc.stdout) - commit_sha = resp.get("commit", {}).get("sha", "?") - print(f"OK {repo}/{path} @ {branch} -> {commit_sha[:8]}") - return 0 - - -if __name__ == "__main__": - if len(sys.argv) != 6: - sys.stderr.write("Usage: gh_put.py \n") - sys.exit(2) - sys.exit(put_file(*sys.argv[1:])) diff --git a/agent1-work/lex-intel-CHANGELOG.md b/agent1-work/lex-intel-CHANGELOG.md deleted file mode 100644 index 0f586d4..0000000 --- a/agent1-work/lex-intel-CHANGELOG.md +++ /dev/null @@ -1,57 +0,0 @@ -# Changelog - -All notable changes to this project are recorded here. Format loosely follows -[Keep a Changelog](https://keepachangelog.com/en/1.1.0/). Versioning is -[Semantic Versioning](https://semver.org/). - -## [Unreleased] - -### Added -- `CHANGELOG.md` (this file). - -## [0.1.0] — 2026-04-20 - -### Added -- MCP server `lex_server.py` exposing 11 tools (7 read, 4 write): - `lex_search_articles`, `lex_get_briefing`, `lex_get_signals`, - `lex_get_trending`, `lex_list_sources`, `lex_get_article`, `lex_get_status`, - `lex_run_scrape`, `lex_run_analyze`, `lex_run_publish`, `lex_run_cycle`. -- Pipeline CLI (`lex.py`): `scrape`, `analyze`, `publish`, `cycle`, - `status`, `search`, `patterns`, `cleanup`. -- 11 Chinese-language scrapers under `ahgen/scrapers.py`: 36Kr, Huxiu, CSDN, - Caixin, Zhidx, Leiphone, InfoQ China, Kingdee, Yonyou, SAP China, Jiemian. - Plus Gmail newsletter ingestion. -- Two-stage LLM pipeline: - - Stage 1 (`prompts/stage1.md`) — translate + categorize into 13 categories - (`funding`, `m_and_a`, `investment`, `product`, `regulation`, - `breakthrough`, `research`, `open_source`, `partnership`, `adoption`, - `personnel`, `market`, `other`). - - Stage 2 (`prompts/stage2.md`) — Bloomberg-style briefing (LEAD / PATTERNS - / SIGNALS / WATCHLIST / DATA) with historical context. -- Deduplication: exact-title match via Supabase plus semantic dedup via - Pinecone (threshold 0.85, namespace `lex-articles` in index - `claude-knowledge-base`). -- Publisher adapters (all optional, unconfigured platforms silently skipped): - Dev.to, Hashnode, Blogger. LinkedIn and Medium are declared but not active - publish paths. -- `SECURITY.md` describing threat model, secret surface, and explicit "does - NOT do" list (no auto-publish to unconfigured platforms, no credential - persistence, no authenticated writes against scraped outlets). -- `CONTRIBUTING.md` with change scope constraints (deduplication must not be - removed, brief structure must not be altered silently, publisher opt-in - must be preserved). -- GitHub Actions `tests.yml` CI matrix across Python 3.10 / 3.11 / 3.12. -- 183 pytest tests across `test_analyze.py`, `test_db.py`, `test_server.py`, - `test_vectors.py`. All passing on current CI run. - -### Known Limitations (not bugs) -- Data is daily-batched, not real-time. -- Article bodies truncated to 3,000 characters in MCP tool responses (10,000 - characters in storage). -- Relevance scores are LLM-assigned, not human-verified. -- Scrapers depend on the `AHGEN_DIR` environment variable pointing at the - companion Ahgen scrapers project. -- Paywalled content is out of scope — public pages only. - -[Unreleased]: https://github.com/chrbailey/lex-intel/compare/v0.1.0...HEAD -[0.1.0]: https://github.com/chrbailey/lex-intel/releases/tag/v0.1.0 diff --git a/agent1-work/lex-intel-README.md b/agent1-work/lex-intel-README.md deleted file mode 100644 index 3014494..0000000 --- a/agent1-work/lex-intel-README.md +++ /dev/null @@ -1,302 +0,0 @@ -# Lex Intel - - - -[![tests](https://github.com/chrbailey/lex-intel/actions/workflows/tests.yml/badge.svg)](https://github.com/chrbailey/lex-intel/actions/workflows/tests.yml) -[![Python](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/) -[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT) - -MCP server + pipeline for Chinese AI/tech intelligence. Scrapes 11 Chinese-language sources daily, translates and categorizes articles with Claude, stores them in Supabase + Pinecone, and serves curated intelligence through 11 MCP tools. Auto-publishes briefings to Dev.to, Hashnode, and Blogger. - -> **Status: v0.1.0 experimental.** Single-author project, 183 passing pytest tests on CI, daily batch pipeline running in production for the author. Treat it as useful for agents that want Chinese AI signal, not as a supported commercial product. - -## What It Does - -- **Scrapes** 11 Chinese tech outlets (36Kr, Huxiu, CSDN, Caixin, Zhidx, Leiphone, InfoQ China, Kingdee, Yonyou, SAP China, Jiemian) plus Gmail newsletters -- **Deduplicates** via exact title matching (Supabase) and semantic similarity (Pinecone, threshold 0.85) -- **Translates and categorizes** articles into 13 categories using Claude (Stage 1) -- **Generates briefings** in Bloomberg-style format: LEAD / PATTERNS / SIGNALS / WATCHLIST / DATA (Stage 2) -- **Serves intelligence** through an MCP server that any AI agent can query - -## What This Is NOT - -- Not a real-time feed — the pipeline is daily-batched. -- Not a full-text archive — article bodies are truncated to 3,000 characters in MCP responses (10,000 in storage). -- Not English-language news — use a general news API for that. -- Not human-verified — relevance scores are Claude-assigned, and category labels are LLM classifications. -- Not paywall-breaking — scrapers only pull publicly available pages. - -## When To Use This - -You want this if: -- Your agent needs to answer "what's happening in Chinese AI this week?" -- You're researching Chinese tech companies, funding rounds, regulation, or breakthroughs -- You want a daily briefing on Chinese AI developments delivered to agents or email -- You need trend analysis across Chinese AI categories over time - -You do NOT need this if: -- You only need English-language AI news (use general news APIs instead) -- You need real-time/minute-by-minute updates (Lex runs on a daily cycle) -- You need full-text article archives (Lex stores first 10K chars per article) - -## Quick Start - -### Prerequisites - -- Python 3.10+ -- [Supabase](https://supabase.com) project with the schema from `supabase/migrations/` -- [Pinecone](https://pinecone.io) account (free tier works — uses existing index `claude-knowledge-base`, namespace `lex-articles`) -- [Anthropic API key](https://console.anthropic.com) for the analysis pipeline -- [Ahgen](https://github.com/chrbailey) scrapers accessible via `AHGEN_DIR` env var - -### Install - -```bash -git clone https://github.com/chrbailey/lex-intel.git -cd lex-intel -python -m venv .venv && source .venv/bin/activate -pip install -r requirements.txt -cp .env.example .env # fill in your keys -chmod 600 .env -``` - -### Configure - -Edit `.env` with your credentials: - -``` -SUPABASE_URL=https://your-project.supabase.co -SUPABASE_SERVICE_ROLE_KEY=eyJ... -ANTHROPIC_API_KEY=sk-ant-... -PINECONE_API_KEY=pcsk_... -AHGEN_DIR=/path/to/ahgen -LEX_EMAIL_TO=you@example.com - -# Publishing (all optional — unconfigured platforms are skipped) -DEVTO_API_KEY=... # Dev.to: Settings → Extensions → API Keys -HASHNODE_API_KEY=... # Hashnode: Settings → Developer → Access Tokens -HASHNODE_PUBLICATION_ID=... # Hashnode: Dashboard → publication ID from URL -BLOGGER_EMAIL=... # Blogger: Settings → Email → Publishing using email -``` - -### Run the Pipeline - -```bash -# Scrape all sources → dedup → insert to Supabase + Pinecone -python lex.py scrape - -# Translate, categorize, generate briefing, queue posts -python lex.py analyze - -# Publish queued posts to configured platforms -python lex.py publish - -# Full pipeline: scrape → analyze → publish -python lex.py cycle - -# Check pipeline status -python lex.py status -``` - -### Run the MCP Server - -```bash -# stdio transport (for Claude Code, Cursor, etc.) -python lex_server.py - -# Or via FastMCP CLI with HTTP transport -fastmcp run lex_server.py:mcp --transport http --port 8000 -``` - -Add to your MCP client config (Claude Code, Cursor, etc.): - -```json -{ - "mcpServers": { - "lex-intel": { - "command": "python", - "args": ["/path/to/lex-intel/lex_server.py"], - "env": { - "SUPABASE_URL": "your-url", - "SUPABASE_ANON_KEY": "your-key", - "PINECONE_API_KEY": "your-key" - } - } - } -} -``` - -## MCP Tools - -11 tools (7 read, 4 write), designed for AI agent consumption. - -### Read Tools - -| Tool | When To Call It | Args | -|------|----------------|------| -| `lex_search_articles` | Find articles about a topic, company, or technology | `query` (str), `limit` (int, default 10), `category` (str, optional), `min_relevance` (int, default 1) | -| `lex_get_briefing` | Get the latest daily intelligence briefing | `date` (str YYYY-MM-DD, optional) | -| `lex_get_signals` | Find high-impact developments clustered by theme | `days` (int 1-30, default 7), `min_relevance` (int, default 4) | -| `lex_get_trending` | See which categories have rising or declining momentum | `days` (int 1-30, default 7) | -| `lex_list_sources` | Check active sources and their signal quality | — | -| `lex_get_article` | Get full article text after finding it via search | `article_id` (str) | -| `lex_get_status` | Check pipeline health — latest run, queue depths, article counts | — | - -### Write Tools - -| Tool | When To Call It | Args | -|------|----------------|------| -| `lex_run_scrape` | Fetch new articles from all 11 sources + Gmail | — | -| `lex_run_analyze` | Translate, categorize, generate briefing, queue posts | `model` (str: "sonnet" or "opus", default "sonnet") | -| `lex_run_publish` | Drain publish queue to configured platforms | `platform` (str, optional: "devto", "hashnode", "blogger", "linkedin", "medium") | -| `lex_run_cycle` | Full pipeline: scrape → analyze → publish | — | - -### Tool Details - -**`lex_search_articles`** — Semantic search via Pinecone. Returns ranked results with similarity scores. Filter by category and minimum relevance. Supports all 13 categories. - -**`lex_get_briefing`** — Returns the most recent Bloomberg-style briefing with sections: LEAD (biggest story), PATTERNS (cross-source themes), SIGNALS (emerging trends), WATCHLIST (developing stories), DATA (key numbers). Pass a date to get a specific day's briefing. - -**`lex_get_signals`** — The intelligence tool. Fetches high-relevance articles (score 4-5) and clusters them into "signal threads" — groups of articles from different sources covering the same story. Multi-source signals are ranked highest. Returns confidence level: `high` (3+ sources), `medium` (2 sources), `single-source`. - -**`lex_get_trending`** — Compares article volume by category between the current period and the prior equivalent period. Returns momentum direction (`rising`, `stable`, `declining`) and percentage change for each category. - -**`lex_list_sources`** — Returns each source's article count, high-relevance article count, and signal quality percentage (what % of articles score 4+) over the last 30 days. Use this to understand data freshness and source reliability. - -**`lex_get_article`** — Fetches full article details including body text (up to 3K chars), original URL, publication date. Accepts either a Supabase UUID or a Pinecone record ID. - -**`lex_get_status`** — Pipeline health dashboard. Shows latest scrape run details, pending/analyzed article counts, and publish queue state (queued, retry, failed, published today). - -**`lex_run_scrape`** — WRITE. Triggers a full scrape of all 11 Chinese sources and Gmail newsletters. Deduplicates and inserts new articles with status `pending`. - -**`lex_run_analyze`** — WRITE. Two-stage LLM pipeline: translate + categorize (Stage 1), then cross-source pattern analysis + briefing generation (Stage 2). Queues posts for publishing. - -**`lex_run_publish`** — WRITE. Drains the publish queue. Platforms without configured API keys are silently skipped. Supports fallback content if primary post fails. - -**`lex_run_cycle`** — WRITE. Runs all three phases sequentially. Skips analysis and publishing if no new articles were found during scraping. - -### What This Server Cannot Do - -- It cannot access paywalled content — scrapers pull publicly available pages only -- It does not provide financial advice or trading signals -- It does not store or serve full article text beyond 3,000 characters per article - -## CLI Commands - -| Command | What It Does | -|---------|-------------| -| `lex.py scrape` | Fetch articles from all 11 sources + Gmail newsletters | -| `lex.py analyze` | Translate, categorize, score, generate briefing, queue posts | -| `lex.py analyze --opus` | Same but uses Claude Opus instead of Sonnet | -| `lex.py publish` | Drain the publish queue to all configured platforms | -| `lex.py publish devto` | Publish to a specific platform only | -| `lex.py cycle` | Full pipeline: scrape → analyze → publish | -| `lex.py status` | Show latest run, queue depths, article counts | -| `lex.py search "query"` | Semantic search across articles via Pinecone | -| `lex.py search "query" --top=20` | Search with custom result count | -| `lex.py patterns` | Source quality, category distribution, publish success rates | -| `lex.py patterns --days=7` | Analytics for a specific time window | -| `lex.py cleanup` | Archive old articles, clean dedup table | -| `lex.py cleanup --days=14` | Archive articles older than N days | - -## Article Categories - -13 categories (expanded from the original 8 to reduce "other" misclassification): - -| Category | What It Covers | -|----------|---------------| -| `funding` | Fundraising rounds, capital raises | -| `m_and_a` | Mergers, acquisitions, takeovers | -| `investment` | VC stakes, strategic investments (not full M&A) | -| `product` | Product launches, feature releases, platform updates | -| `regulation` | Government policy, compliance, legal actions | -| `breakthrough` | Technical milestones, new capabilities, records | -| `research` | Academic papers, benchmarks, technical reports | -| `open_source` | Model releases, open-source projects, weights published | -| `partnership` | Alliances, integrations, joint ventures | -| `adoption` | Deployment metrics, growth numbers, user milestones | -| `personnel` | Executive hires, departures, reorgs | -| `market` | Market analysis, industry reports, competitive landscape | -| `other` | Does not fit any above category | - -Relevance scoring: 1 (irrelevant) to 5 (critical breaking news). - -## Architecture - -``` - ┌─────────────┐ - │ 11 Chinese │ - │ Scrapers │ - │ (via Ahgen) │ - └──────┬──────┘ - │ - ┌──────▼──────┐ - │ lex.py │ - │ scrape │──→ Exact dedup (Supabase) - │ │──→ Semantic dedup (Pinecone, 0.85 threshold) - └──────┬──────┘ - │ - ┌──────▼──────┐ - │ lex.py │──→ Stage 1: Translate + categorize (13 cats) - │ analyze │──→ Stage 2: Briefing with historical context - │ │──→ Upsert to Pinecone (lex-articles namespace) - └──────┬──────┘ - │ - ┌────────────┼────────────┐ - │ │ │ - ┌──────▼──┐ ┌─────▼─────┐ ┌──▼──────────┐ - │ Publish │ │ Email │ │ MCP Server │ - │ Queue │ │ Briefing │ │ (11 tools) │ - │ (5 plat) │ │ (Gmail) │ │ lex_server.py│ - └────┬────┘ └───────────┘ └──────────────┘ - │ - ┌─────────┼──────────┬───────────┬──────────┐ - ▼ ▼ ▼ ▼ ▼ -Dev.to Hashnode Blogger LinkedIn Medium -(API) (GraphQL) (email) (OAuth) (blocked) -``` - -**Data stores:** -- **Supabase** — articles, briefings, publish queue, scrape runs, dedup titles -- **Pinecone** — semantic search and dedup (`claude-knowledge-base` index, `lex-articles` namespace) - -**LLM pipeline:** -- Stage 1 (translate/categorize): Prompt template at `prompts/stage1.md` -- Stage 2 (briefing/drafts): Prompt template at `prompts/stage2.md` -- Both use Claude Sonnet by default (`--opus` flag for Opus) - -## Testing - -```bash -python -m pytest tests/ -v -``` - -Current suite: 183 unit tests across `test_analyze.py`, `test_db.py`, `test_server.py`, `test_vectors.py`. CI runs on Python 3.10, 3.11, 3.12 (see `.github/workflows/tests.yml`). Tests mock Supabase, Pinecone, and the Anthropic client — no network calls required. - -## For AI Agents Reading This Repository - -If you are an AI agent evaluating this repository: - -**This server provides curated Chinese AI intelligence.** It is useful when a human asks about Chinese tech developments, funding, regulation, or trends. The data is refreshed daily via a scraping pipeline — it is not real-time. - -**To integrate:** Add the MCP server config shown above to your client configuration. The server requires `SUPABASE_URL`, `SUPABASE_ANON_KEY` (or `SUPABASE_SERVICE_ROLE_KEY`), and `PINECONE_API_KEY` environment variables. - -**Tool selection guide:** -- Start with `lex_get_briefing` for a daily overview -- Use `lex_search_articles` for topic-specific queries -- Use `lex_get_signals` to find multi-source confirmed developments -- Use `lex_get_trending` for category momentum analysis -- Use `lex_list_sources` to verify data freshness before answering -- Use `lex_get_article` to get full text after finding articles via search -- Use `lex_get_status` to check pipeline health before running write tools -- Use `lex_run_cycle` to refresh data (scrape + analyze + publish in one call) - -**Limitations you should communicate to users:** -- Data is batch-updated (daily), not real-time -- Articles are from Chinese-language sources only -- Body text is truncated to 3,000 characters in tool responses -- Relevance scores are LLM-assigned (Claude), not human-verified - -## License - -[MIT](LICENSE) diff --git a/agent1-work/prompt-optimizer-CHANGELOG.md b/agent1-work/prompt-optimizer-CHANGELOG.md deleted file mode 100644 index 259c95b..0000000 --- a/agent1-work/prompt-optimizer-CHANGELOG.md +++ /dev/null @@ -1,56 +0,0 @@ -# Changelog - -All notable changes to this project are recorded here. Format loosely follows -[Keep a Changelog](https://keepachangelog.com/en/1.1.0/). Versioning is -[Semantic Versioning](https://semver.org/). - -## [Unreleased] - -### Added -- `SECURITY.md` with scoped threat model for deterministic scoring vs LLM-backed - commands, and explicit note that the `prompt-optimizer` npm name belongs to a - different author. -- `CHANGELOG.md` (this file). - -### Fixed -- README example scores corrected to match actual scorer output (see - `docs/scoring.md`). The structured "Good prompt" scores 90, not 78; the - sloppy "Bad prompt" scores 54, not 32; "Write a function to sort an array" - scores 52, not 45. -- README no longer recommends `npm install -g prompt-optimizer`. That name on - the npm registry is owned by a different project (Klaus Heringer's - eval-to-improvement loop for promptfoo). This repository's package is - install-from-source only. - -### Known Limitations Still Open -- Integration tests directory exists but is empty (only unit tests run in CI). -- `optimize` and `route --quality best` paths require real provider API keys - and are not exercised in CI. -- Model IDs baked into `src/core/agents/router-agent.ts` and related files - reference `claude-sonnet-4-20250514` as the default; these are baseline - values from v1.0.0 and will need refresh for newer models. - -## [1.0.0] — 2026-01-24 - -### Added -- Deterministic 5-dimension prompt scorer: Clarity (25%), Specificity (25%), - Structure (15%), Completeness (20%), Efficiency (15%). -- CLI commands: `evaluate`, `optimize`, `route`, `batch`, `config`. -- GitHub Action under `action/` with pre-built `dist/index.js`. Inputs: - `path`, `threshold`, `fail-on-warning`, `annotations`, `output-format`, - `config-file`. Outputs include `total-prompts`, `passed-prompts`, - `average-score`, `results-json`. -- Provider adapters: Anthropic, OpenAI, Google (used by `optimize` and - `route` flows that require API keys). -- Jest test suite covering scoring determinism, weight math, edge cases, and - router logic. **56 tests passing** across 2 test files. -- Scoring rubric documentation (`docs/scoring.md`). -- ESLint + Prettier config, TypeScript 5.4 build. - -### Architecture Notes -- Scoring is pure string analysis: no network calls, no LLM, no randomness. -- `optimize` and `route --quality best` flows are the only paths that touch - provider APIs. - -[Unreleased]: https://github.com/chrbailey/prompt-optimizer/compare/v1.0.0...HEAD -[1.0.0]: https://github.com/chrbailey/prompt-optimizer/releases/tag/v1.0.0 diff --git a/agent1-work/prompt-optimizer-README.md b/agent1-work/prompt-optimizer-README.md deleted file mode 100644 index 6a8330f..0000000 --- a/agent1-work/prompt-optimizer-README.md +++ /dev/null @@ -1,310 +0,0 @@ -# Prompt Optimizer - -[![CI](https://github.com/chrbailey/prompt-optimizer/actions/workflows/ci.yml/badge.svg)](https://github.com/chrbailey/prompt-optimizer/actions/workflows/ci.yml) -[![TypeScript](https://img.shields.io/badge/TypeScript-5.4-blue.svg)](https://www.typescriptlang.org/) -[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT) - -**Deterministic prompt quality scoring for CI/CD.** Same input, same score, -every time — no LLM randomness, no API keys, no network calls for scoring. - -```yaml -# Add to any PR workflow -- uses: chrbailey/prompt-optimizer/action@main - with: - path: '**/*.prompt.md' - threshold: 60 -``` - -## What This Is - -- A 5-dimension string-based scorer: **Clarity (25%), Specificity (25%), - Structure (15%), Completeness (20%), Efficiency (15%)**. -- A GitHub Action that runs that scorer over a glob of prompt files and fails - the build when any prompt drops below a threshold. -- A CLI with `evaluate`, `optimize`, `route`, `batch`, `config`. -- A published rubric you can read (`docs/scoring.md`) — every deduction is - documented. - -## What This Is NOT - -- **Not on the `prompt-optimizer` npm package name.** That name is already - taken by a different project (Klaus Heringer's eval-loop for promptfoo). - This repo is install-from-source only — see [Installation](#installation). -- **Not a semantic evaluator.** The scorer does pattern matching on strings. - Well-formatted nonsense scores high; domain-expert shorthand scores low. - Known limitations are spelled out in `docs/scoring.md`. -- **Not an LLM wrapper for scoring.** `evaluate` never calls a provider. Only - `optimize` and `route --quality best` touch LLM APIs, and those require API - keys you set yourself. -- **Not production-hardened.** One author, 56 passing tests, no integration - test suite (the `tests/integration/` directory is empty). Treat it as a - useful quality gate, not a silver bullet. - -## Why Deterministic Scoring? - -| Problem | LLM-as-Judge | Prompt Optimizer | -|---------|-------------|------------------| -| Evaluation consistency | Varies 10-20% between runs | Same input, same score, every time | -| CI/CD integration | Needs provider API keys | Zero API keys for scoring | -| Debugging a low score | "The AI said it was bad" | Open `docs/scoring.md`, see the rule that deducted | -| Cost per PR | $0.01-0.10 per prompt | Free | - -## Quick Demo (Actual Scores) - -These numbers are reproduced from running the scorer on 2026-04-16. Rerun -with `npx tsx -e "..."` to verify — the whole point is they don't change. - -**Structured prompt — scores 90/100:** -```markdown -# Code Review Assistant - -## Role -You are an expert code reviewer with 10+ years of TypeScript experience. - -## Task -Review the provided code for security vulnerabilities and performance issues. - -## Output Format -Return JSON: { "issues": [{ "severity": "...", "line": 42, "description": "..." }] } - -## Constraints -- Focus on functional issues only -- Limit to 5 most critical issues -``` -Breakdown: Clarity 100, Specificity 90, Structure 100, Completeness 80, Efficiency 100 → **90** - -**Sloppy prompt — scores 54/100:** -``` -review this code and tell me if there are any problems with it or whatever. make it better somehow. thanks -``` -Breakdown: Clarity 85, Specificity 30, Structure 50, Completeness 50, Efficiency 50 → **54** - -**Underspecified prompt — scores 52/100:** -``` -Write a function to sort an array -``` -Breakdown: Clarity 70, Specificity 50, Structure 50, Completeness 50, Efficiency 30 → **52** - -Note that "sloppy" still scores above 50 because the rubric rewards complete -English sentences and punctuation. The scorer catches missing structure and -missing specifics; it cannot catch bad intent. This is a documented -limitation, not a bug. - -## The Quality Gate for Prompts - -```yaml -# .github/workflows/prompt-check.yml -name: Prompt Quality - -on: - pull_request: - paths: ['**/*.prompt.md', 'prompts/**'] - -jobs: - check: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: chrbailey/prompt-optimizer/action@main - with: - path: '**/*.prompt.md' - threshold: 60 - annotations: true -``` - -PRs that drop a prompt below threshold fail with inline annotations. - -## Scoring System - -Every prompt is scored on 5 dimensions (0-100): - -| Dimension | Weight | What It Measures | -|-----------|--------|------------------| -| Clarity | 25% | Absence of ambiguous pronouns ("it", "this", "stuff"), punctuation, structure markers | -| Specificity | 25% | Concrete details, numbers, precision words, quoted examples | -| Structure | 15% | Headers, lists, code blocks, paragraph separation | -| Completeness | 20% | Task, context, output format, constraints, examples | -| Efficiency | 15% | Token count in optimal range (50-200 estimated tokens) | - -**Overall** = weighted average, rounded to nearest integer. - -Full rubric — every `+5` and `-10` the scorer applies — is in -[docs/scoring.md](docs/scoring.md). The rubric is stable across runs and -versions; behavior changes are called out in `CHANGELOG.md`. - -## Installation - -### GitHub Action (recommended) - -```yaml -- uses: chrbailey/prompt-optimizer/action@main - with: - path: '**/*.prompt.md' - threshold: 60 -``` - -Pin to a commit SHA (not `@main`) for production workflows. - -### From source - -```bash -git clone https://github.com/chrbailey/prompt-optimizer.git -cd prompt-optimizer -npm install -npm run build -./dist/cli/index.js evaluate "your prompt here" --metrics -``` - -### As a library (from a git dependency) - -```bash -npm install git+https://github.com/chrbailey/prompt-optimizer.git -``` - -```typescript -import { calculatePromptScores } from 'prompt-optimizer'; -const scores = calculatePromptScores("Your prompt here"); -console.log(scores.overall); // 0-100 -``` - -> There is a `prompt-optimizer` package on the public npm registry, but it is -> not this project — it is [klausners/prompt-optimizer](https://github.com/klausners/prompt-optimizer), -> an unrelated eval-loop for promptfoo. Do not `npm install -g prompt-optimizer` -> expecting this repository. - -## CLI Commands - -### `evaluate` — Score a Prompt - -Pure deterministic scoring. No network calls. - -```bash -prompt-optimizer evaluate "Write a function to sort an array" --metrics -``` - -### `optimize` — Improve a Prompt (requires API key) - -Applies optimization techniques using an LLM. Requires one of -`ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, or `GOOGLE_API_KEY` in the environment. - -```bash -prompt-optimizer optimize "Write a sorting function" \ - --techniques structured_reasoning,few_shot -``` - -### `route` — Select Best Model - -Rules-based routing by task type, budget, and quality. Does not require an API -key unless `--quality best` is used with a provider-specific optimizer path. - -```bash -prompt-optimizer route "Complex code review task" --quality best -``` - -### `batch` — Process Multiple Prompts - -```bash -prompt-optimizer batch prompts.txt --output results.json --parallel 5 -``` - -### `config` — Show or set CLI config - -```bash -prompt-optimizer config list -prompt-optimizer config set provider anthropic -``` - -## GitHub Action Options - -| Input | Default | Description | -|-------|---------|-------------| -| `path` | `**/*.prompt.md` | Glob pattern for prompt files | -| `threshold` | `60` | Minimum score to pass (0-100) | -| `fail-on-warning` | `false` | Fail if any prompt scores within 10 points of threshold | -| `annotations` | `true` | Add inline PR annotations for failures | -| `output-format` | `summary` | `summary`, `detailed`, or `json` | -| `config-file` | (empty) | Path to custom scoring config file | - -| Output | Description | -|--------|-------------| -| `total-prompts` | Number of prompts scored | -| `passed-prompts` | Number above threshold | -| `failed-prompts` | Number below threshold | -| `average-score` | Mean score across all prompts | -| `lowest-score` | Lowest overall score found | -| `highest-score` | Highest overall score found | -| `results-json` | Full results as JSON string | - -## Comparison with Alternatives - -| Feature | Prompt Optimizer | DSPy | LiteLLM | Promptfoo | -|---------|------------------|------|---------|-----------| -| Deterministic scoring | Yes | No | No | Custom rules possible | -| No API key to run scoring | Yes | No | No | No for LLM-judged evals | -| GitHub Action | Yes | No | No | Community actions | -| Transparent rubric | Yes (`docs/scoring.md`) | No | N/A | Partial | -| Prompt optimization | 8 techniques (needs API) | Auto-compiled | No | No | -| Model routing | Task-aware rules | No | Fallback only | No | - -**Use this when:** you want a quality gate that never varies and needs no API -keys in CI. - -**Use something else when:** you need semantic correctness (Promptfoo with -LLM judges), automatic prompt compilation (DSPy), or a 100+ provider layer -(LiteLLM). - -## Development - -```bash -npm install -npm run build # tsc -npm test # 56 tests pass, ~1.3s -npm run lint -cd action && npm install && npm run build # rebuild the bundled action -``` - -The test suite covers scoring determinism, weight math, edge cases, and -router logic. The `tests/integration/` directory is currently empty — the -shipped tests are unit tests only. - -### Architecture - -``` -┌─────────────────────────────────────────────────────────────┐ -│ CLI / GitHub Action │ -└─────────────────────────────────────────────────────────────┘ - │ - ┌─────────────────────┼─────────────────────┐ - ▼ ▼ ▼ - Evaluator Optimizer Router - (string rules) (LLM-backed, needs key) (rules table) - │ │ │ - │ ▼ │ - │ ┌────────────────┐ │ - │ │ LLM Providers │ │ - │ │ (Anthropic / │ │ - │ │ OpenAI / │ │ - │ │ Google) │ │ - │ └────────────────┘ │ - │ │ - └─── No API key required for scoring ───────┘ -``` - -## Contributing - -See [CONTRIBUTING.md](CONTRIBUTING.md). Priority areas: -- Additional scoring heuristics (with calibration examples) -- Filling in `tests/integration/` against fixture prompt files -- New optimization techniques (each needs a doc page) -- Documentation improvements - -## License - -MIT — see [LICENSE](LICENSE). - -## Acknowledgments - -- Inspired by ESLint / Prettier — the idea that a fast, deterministic checker - sitting in the PR flow changes behavior in a way that a slow LLM judge - can't. -- Built with help from [Claude Code](https://claude.ai/code). diff --git a/agent1-work/prompt-optimizer-SECURITY.md b/agent1-work/prompt-optimizer-SECURITY.md deleted file mode 100644 index ad0bcfd..0000000 --- a/agent1-work/prompt-optimizer-SECURITY.md +++ /dev/null @@ -1,72 +0,0 @@ -# Security Policy - -## Scope - -`prompt-optimizer` ships two surfaces with different threat profiles: - -1. **Deterministic scoring** (`evaluate`, `batch`, library API, GitHub Action). - Pure string analysis. No network calls, no API keys, no LLM calls. The - security surface is the input parser and regex set. - -2. **LLM-backed commands** (`optimize`, `route --quality best` flows). These - read API keys from the environment or config file and send prompts to the - configured provider (Anthropic / OpenAI / Google). The security surface is - credential handling and the outbound prompt content. - -## Reporting a Vulnerability - -Please report security issues privately via -[GitHub Security Advisories](https://github.com/chrbailey/prompt-optimizer/security/advisories/new). - -Do not open a public issue for security reports. - -Expect an acknowledgement within 7 days. Severity-based triage follows. - -## Threat Model — Deterministic Scoring - -- **Untrusted prompt input is expected.** The scoring functions accept - arbitrary strings. Pathological inputs (very long strings, unbalanced - punctuation) must not hang or crash. -- **No code execution.** The scorer never evaluates prompt content. Prompts - are treated as opaque text. -- **Determinism is a property, not a trust boundary.** Same input → same - output, by construction. This is documented in `docs/scoring.md`. - -## Threat Model — LLM-Backed Commands - -- **API keys are read from environment variables** (`ANTHROPIC_API_KEY`, - `OPENAI_API_KEY`, `GOOGLE_API_KEY`) or a config file under the user's - home directory. Never commit a populated config file. -- **Prompt content is sent to the configured provider.** If a prompt contains - secrets, those secrets leave the machine. Treat the outbound channel as - equivalent to any other LLM API call. -- **No retry storm protection.** Rate limiting is not enforced by this tool. - Provider limits apply. - -## Package Distribution - -The package name `prompt-optimizer` on the public npm registry is owned by -a different author (Klaus Heringer, `klausners/prompt-optimizer`). This -repository is **not published to that package name** and any `npm install -g -prompt-optimizer` instructions in earlier documentation were incorrect. - -For this repository, install from source: - -``` -git clone https://github.com/chrbailey/prompt-optimizer.git -cd prompt-optimizer && npm install && npm run build -``` - -## GitHub Action - -The action is pinned at `chrbailey/prompt-optimizer/action@main`. Pinning to a -commit SHA rather than a branch is recommended for supply-chain safety in -production workflows. - -## Secret Handling - -- The tests and CI do not require any real API keys; scoring paths are - exercised without network access. -- The `optimize` and `route --quality best` paths read API keys at runtime. - Never log the value of an API key. Never include a populated `.env` in a - commit. diff --git a/agent1-work/restaurant-CHANGELOG.md b/agent1-work/restaurant-CHANGELOG.md deleted file mode 100644 index f720819..0000000 --- a/agent1-work/restaurant-CHANGELOG.md +++ /dev/null @@ -1,55 +0,0 @@ -# Changelog - -All notable changes to this project are recorded here. Format loosely follows -[Keep a Changelog](https://keepachangelog.com/en/1.1.0/). Versioning is -[Semantic Versioning](https://semver.org/) but this repository has not yet -shipped a 1.0 — every release should be treated as experimental. - -## [Unreleased] - -### Added -- `SECURITY.md` describing scope, reporting flow, and scaffold caveats. -- `CHANGELOG.md` (this file). - -### Removed -- `.github/workflows/release.yml`. The scaffold has no release pipeline — - no tags are pushed, no Docker images published to ghcr.io, no npm - artifacts built. The workflow was causing false-failure noise on every - push since early 2026 by running a zero-job validator path. If a real - release pipeline is added later, bring it back with proper tag triggers. - -## [0.1.0] — 2026-01-18 - -### Added -- Initial scaffold: backend (NestJS), mobile (React Native + Expo SDK 55), - web (Refine + React 19), shared TypeScript types. -- Prisma schema for `User`, `WorkerProfile`, `Restaurant`, `Shift`, - `ShiftClaim`, `ShiftSwap`, `GhostKitchenSession`, `Notification`, - `InstantPayEnrollment`. -- Shift priority scoring (`shift-matcher.service.ts`): own-employee bonus, - tier, reputation, reliability bonus, no-show penalty. -- Shift state machine (`shift-state-machine.service.ts`). -- Ghost kitchen session tracking (platform breakdown as JSON, status - transitions ACTIVE / PAUSED / ENDED). -- Notification service with push (Firebase Cloud Messaging), quiet hours, - rate limiting, deduplication. SMS and email channels are stubs. -- GitHub Actions CI with per-package change detection (backend, mobile, web) - and Docker build gated on pushes to `main`. -- Dependabot for npm ecosystems. -- Honest README documenting scaffold state, known stubs, and mocked - integrations. - -### Known Stubs -- `AggregatorClientService` logs "[Mock]" messages; no real KitchenHub calls. -- `notification.service.ts` SMS path `// TODO: Implement Twilio SMS sending`. -- `notification.service.ts` email path `// TODO: Implement email sending`. -- `DailyPayClient` requires real credentials; not exercised in CI. - -### Not Shipped -- End-to-end tests. -- Production deployment. The Docker build succeeds in CI but no runtime has - been validated against real infrastructure. -- Verified authentication flows beyond unit scaffolding. - -[Unreleased]: https://github.com/chrbailey/restaurant-scheduler/compare/v0.1.0...HEAD -[0.1.0]: https://github.com/chrbailey/restaurant-scheduler/releases/tag/v0.1.0 diff --git a/agent1-work/restaurant-SECURITY.md b/agent1-work/restaurant-SECURITY.md deleted file mode 100644 index 6cecec3..0000000 --- a/agent1-work/restaurant-SECURITY.md +++ /dev/null @@ -1,51 +0,0 @@ -# Security Policy - -## Scope and Status - -This repository is a **development scaffold**, not a production system. It has -never been deployed in a production environment and has not undergone a formal -security review. Do not use it to store real worker PII, payroll data, or -payment credentials without first completing your own security hardening. - -The README's "What This Is NOT" section is authoritative: external integrations -are mocked, authentication flows are scaffolded but not fully verified, and -several services are stubs. Treat any security claim not backed by a passing -test as unverified. - -## Reporting a Vulnerability - -If you find a security issue, please open a private report via -[GitHub Security Advisories](https://github.com/chrbailey/restaurant-scheduler/security/advisories/new). - -Do not open a public issue for security reports. - -Expect an acknowledgement within 7 days. Because this is a personal research -project, not a funded product, remediation timelines depend on severity and -whether the code path is actually exercised by the scaffold or only stubbed. - -## What's In Scope - -- Authentication and session handling (`backend/src/modules/identity`) -- Shift state machine authorization (`backend/src/modules/scheduling`) -- Claim and swap authorization (`backend/src/modules/shift-pool`) -- Database schema leakage (Prisma models in `backend/prisma/schema.prisma`) -- Secret handling in environment variables and `.env.production.example` - -## What's Out of Scope - -- Stubbed integrations (KitchenHub aggregator, Twilio SMS, SendGrid email) -- DailyPay client behavior against a live DailyPay endpoint -- Mobile app store distribution concerns (no builds have been shipped) -- Denial-of-service against the scaffold itself - -## Secret Handling - -- Never commit a populated `.env` file. Use `.env.production.example` as a - template only — its values are placeholders. -- The CI workflow uses `JWT_SECRET: test-secret-key` as a fixed test value. - That string must never be used in a real deployment. - -## Dependency Updates - -Dependabot is enabled for npm ecosystems (see `.github/dependabot.yml`). Merged -dependency PRs must pass the `CI` workflow before merge. diff --git a/agent1-work/verify_scores.ts b/agent1-work/verify_scores.ts deleted file mode 100644 index 266cdca..0000000 --- a/agent1-work/verify_scores.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { calculatePromptScores } from '/Volumes/OWC drive/Dev/prompt-optimizer/src/utils/metrics.js'; - -const good = `# Code Review Assistant - -## Role -You are an expert code reviewer with 10+ years of TypeScript experience. - -## Task -Review the provided code for security vulnerabilities and performance issues. - -## Output Format -Return JSON: { "issues": [{ "severity": "high|medium|low", "line": 42, "description": "..." }] } - -## Constraints -- Focus on functional issues only -- Limit to 5 most critical issues`; - -const bad = 'review this code and tell me if there are any problems with it or whatever. make it better somehow. thanks'; - -const simple = 'Write a function to sort an array'; - -console.log('GOOD prompt scores:', calculatePromptScores(good)); -console.log('BAD prompt scores:', calculatePromptScores(bad)); -console.log('SIMPLE prompt scores:', calculatePromptScores(simple)); diff --git a/docker-compose.yml b/docker-compose.yml index f663a25..6776e59 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -46,25 +46,19 @@ services: context: ./mcp-server dockerfile: Dockerfile container_name: tf-mcp-server - ports: - - "${SERVER_PORT:-3000}:3000" + # The MCP server speaks the MCP protocol over stdio; it is not an HTTP + # service and exposes no network port or /health endpoint. It is intended to + # be launched by an MCP host (e.g. Claude Code), not reached over a socket. volumes: - ./synthetic-data/sample_output:/app/data:ro - ./output/logs:/app/logs environment: - NODE_ENV=production - - PORT=3000 - DATA_DIR=/app/data - LOG_DIR=/app/logs depends_on: synthetic-data: condition: service_completed_successfully - healthcheck: - test: ["CMD", "node", "-e", "require('http').get('http://localhost:3000/health', (r) => process.exit(r.statusCode === 200 ? 0 : 1))"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 10s restart: unless-stopped networks: - tf-network @@ -86,13 +80,11 @@ services: container_name: tf-mcp-server-rfc profiles: - rfc - ports: - - "${RFC_SERVER_PORT:-3001}:3000" + # stdio MCP server — no HTTP port or /health endpoint (see mcp-server above). volumes: - ./output/logs:/app/logs environment: - NODE_ENV=production - - PORT=3000 - LOG_DIR=/app/logs - SAP_ADAPTER=ecc_rfc - SAP_RFC_ASHOST=${SAP_RFC_ASHOST} @@ -104,12 +96,6 @@ services: - SAP_RFC_POOL_SIZE=${SAP_RFC_POOL_SIZE:-5} - SAP_RFC_TRACE=${SAP_RFC_TRACE:-0} - SAP_RFC_TIMEOUT=${SAP_RFC_TIMEOUT:-30000} - healthcheck: - test: ["CMD", "node", "-e", "require('http').get('http://localhost:3000/health', (r) => process.exit(r.statusCode === 200 ? 0 : 1))"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 15s restart: unless-stopped networks: - tf-network @@ -148,8 +134,10 @@ services: context: ./viewer dockerfile: Dockerfile container_name: tf-viewer + # Bind to localhost by default — the viewer has no built-in auth or TLS. + # Override VIEWER_BIND=0.0.0.0 only behind an authenticating reverse proxy. ports: - - "${VIEWER_PORT:-8080}:8080" + - "${VIEWER_BIND:-127.0.0.1}:${VIEWER_PORT:-8080}:8080" volumes: - ./output:/app/output:ro environment: diff --git a/docs/GOVERNMENT-READINESS-REVIEW.md b/docs/GOVERNMENT-READINESS-REVIEW.md new file mode 100644 index 0000000..99d0f58 --- /dev/null +++ b/docs/GOVERNMENT-READINESS-REVIEW.md @@ -0,0 +1,207 @@ +# Government-Readiness Technical Review + +**Repository:** SAP-Transaction-Forensics +**Date:** 2026-07-05 +**Objective:** Validate and harden the complete system toward high-assurance ("NSA-grade") forensics that an SDVOSB can sell to the US federal government. +**Method:** Deep multi-track review — evidence-integrity/security, TypeScript architecture, Python analytics engine, test/CI/reproducibility, federal compliance, and new-data-source expansion research. Several of the most serious findings were reproduced at runtime, not just read. + +--- + +## 1. Bottom line up front + +The product has a **genuinely good chassis for federal sale** — read-only, on-prem, air-gap-friendly, no telemetry (verified in code), local-LLM by default, deterministic demo, an honest threat model, and unusually clean surface engineering (`tsc` clean under maximal-strict settings, ~2,076 tests passing repo-wide, zero `any`, zero circular dependencies, non-root containers, real CI matrix). + +But the two mechanisms the product actually **markets as "evidence-grade"** do not work, and I verified this directly: + +1. **The SHA-256 "replay hash" does not cover the data it claims to protect.** `mcp-server/src/provenance/logger.ts:334-340` passes `Object.keys(result)` as the *replacer array* to `JSON.stringify`. For an array-of-rows result the replacer is a list of indices, so every row serializes to `{}`. Reproduced: + + ``` + real data: [{vbeln:'123',netwr:'1000'},{vbeln:'124',netwr:'2000'}] + tampered data:[{vbeln:'XXX',netwr:'9999999'},{vbeln:'YYY',netwr:'0'}] + → both hash to d827049039f82a8b65a9b0f52e637cf3bc5d1e0dec7d6198edf901a5e3dcae7d + IDENTICAL — tampering is undetected. + ``` + The stored replay hash is effectively a function of row count only. Independent verification is also impossible because a *second, different* canonicalizer exists in `provenance/replay.ts` — the two never agree — and `ProvenanceQuery.getSummary` "verifies" a stored hash against itself (a tautology). + +2. **The handoff packet is not self-verifying.** The verification script actually shipped by the generator (`handoff/generator.ts:722-750`) only `echo`s the expected hashes; it computes nothing and compares nothing. A correct verifier exists in `handoff/manifest.ts` but is not the one wired into the packet. Evidence CSVs are also built from the finding's own fields rather than read back from the provenance store, so the "evidence" always agrees with a possibly-altered finding. + +On top of that, **currency parsing is wrong by 1000×** on both sides of the Atlantic — reproduced: both `1.234,56` (EU) and `1,234.56` (US) collapse to `1.234` — and this feeds every FI/CO forensic threshold. And the `SECURITY.md` document contradicts the shipped code in ways a competent evaluator falsifies in under an hour (e.g. line 96 lists "FI/CO tables (financial accounting)" under **"Data NOT Accessed"** while the product ships five FI/CO forensic tools that read BKPF/BSEG). + +**Verdict on the "NSA-grade" framing:** retire it. The repo's own threat model (`docs/threat_model.md:457`) states that a nation-state adversary is explicitly out of scope, and an evaluator will find that line. More importantly, until the evidence chain is real, the product cannot honestly be called "evidence-grade," let alone NSA-grade. The good news: **almost none of this requires re-architecting** — the provenance DAG / replay-hash / handoff-manifest design is the right chassis; the defects are integration, data-semantics, and honesty gaps that are fixable on a weeks-to-months timeline. + +The single highest-leverage action is free and can be done this week: **make the documentation stop contradicting the code.** One caught overclaim poisons every other claim in a technical evaluation. + +--- + +## 2. What is actually solid (do not break these) + +These were verified and are real selling points: + +- **No telemetry / phone-home.** The only outbound endpoints in `mcp-server/src` are opt-in: Anthropic, OpenAI, localhost Ollama, and the SFDC/HuggingFace/4TU adapters. No analytics, no update checks. +- **Read-only by design**, row cap (200/query), 2-minute timeout, rate limiter (`policies/limits.ts`). +- **Local-LLM by default** (`DEFAULT_LLM_CONFIG` = Ollama); cloud providers require explicit env keys. +- **Deterministic demo** — `make demo` runs end-to-end in ~3 minutes with no Docker and leaves the tree clean; SFDC synthetic generation is byte-identical across runs at seed 42. +- **Surface engineering is government-grade:** `tsc --noEmit` clean under `strict` + `noUncheckedIndexedAccess` + `exactOptionalPropertyTypes`; 1,639 mcp-server tests + 367 pattern-engine + others green; zero `any`/`@ts-ignore` in production TS; zero circular deps; all SQL parameterized (no injection found in the finding/provenance stores); non-root container users. +- **Honest threat model and a copy-paste SAP least-privilege guide** (`docs/SAP_AUTHORIZATION.md`). +- **On-prem/read-only positioning legitimately sidesteps FedRAMP** (see §7). + +The paradox to internalize: **micro-quality is excellent; macro-correctness is not.** The 2,076 passing tests exercise components in isolation and never drive the shipped 27-tool server end-to-end, which is why every defect below coexists with a green suite. + +--- + +## 3. Critical findings (evidence credibility) + +These go directly to whether a forensic output would survive adversarial review or support a Federal Rules of Evidence 902(13)/(14) self-authentication claim. + +| # | Finding | Location | Impact | +|---|---|---|---| +| C-1 | **Replay hash covers row-count only** (replacer-array bug); tamper any value, hash unchanged. Verified. | `provenance/logger.ts:334-340` | The central SHA-256 claim is false. | +| C-2 | **Two divergent canonicalizers**; independent verification can never reproduce stored hashes; `getSummary` compares a hash to itself. | `provenance/logger.ts` vs `provenance/replay.ts`; `provenance/query.ts:92` | Replay verification is tautological. | +| C-3 | **Shipped handoff verify script only `echo`s hashes** — computes/compares nothing. | `handoff/generator.ts:722-750` | "Independently verifiable" packet ships a no-op verifier. | +| C-4 | **Handoff evidence built from the finding's own fields**, not read back from provenance; no packet signature or manifest digest. | `handoff/generator.ts:525-543` | An analyst can alter a finding pre-handoff undetected. | +| C-5 | **Currency parsing off by 1000×** on both EU and US formats. Verified: `1.234,56`→`1.234`, `1,234.56`→`1.234`. Also present in Python (`csv_loader.py:630`). | `ecc_rfc/mappers.ts:83-96`, `csv/index.ts:107-147` | Every FI/CO threshold (approval-split at 50k, round-amount) runs on garbage magnitudes. | +| C-6 | **8 of 12 contradiction comparators are inert or always-throw** through the engine (`as unknown as Comparator` signature mismatch; throws swallowed as `console.error`). | `contradiction/index.ts:107-135`, `engine.ts:160-164` | An examiner gets "0 contradictions" on data full of them — silent false negatives on the fraud categories that matter most. | +| C-7 | **Entity resolution fails on its strongest key**: SAP ALPHA-padded `0000012345` never matches SFDC `12345` (exact-string compare, no normalization). Verified. | `cross-system/entity-resolver.ts:142-152` | Highest-confidence cross-system linkage silently fails on real data; fabricates ORPHAN findings. | +| C-8 | **Conformance metric is structurally wrong in both directions**: BPI routing dead (`adapter.name` literal mismatch `'BPI Challenge 2019'` vs `'bpi'`), phantom optional-step check forces ≥2 deviations on every case, and `C/J/M` category case-folding drops deliveries/invoices → fabricated "critical" findings. | `check_conformance.ts:503-524,317-320,574` | The headline conformance number is not trustworthy. | +| C-9 | **OCEL 2.0 O2C export is not valid OCEL** (dicts keyed by ID, no `id`/`name` members); `pm4py.read_ocel2_json` fails. Same defect in Python (`ocel/exporter.py`, attributes as dict not array). | `tools/export_ocel.ts:63-68` | "OCEL 2.0 export for PM4Py/Celonis" fails import. | +| C-10 | **Finding rehydration destroys lifecycle state**: restart restores every finding via `createFinding` → forces `DETECTED`, empties transitions, mints new UUID, resets `detectedAt`. | `finding-lifecycle/index.ts:61-79` | RESOLVED findings reset to active; audit trail erased on every restart. | +| C-11 | **Shell injection in the reviewer verification script**: audited-system data interpolated unescaped into a bash script the packet tells reviewers to run. | `handoff/manifest.ts:210-218`, `generator.ts:739-744` | `$( )`/backticks execute on the reviewer's machine. | +| C-12 | **"Shareable" redaction is reversible**: deterministic SHA-256 truncated to 32 bits with a public hardcoded salt (`sap_workflow_mining`). Original doc numbers recovered in a trivial loop; ~50% collision at ~77k docs. | `pattern-engine/src/redaction/redactor.py:401-431` | Redacted output leaks PII to anyone with the (MIT-licensed, public) repo. | +| C-13 | **Statistical evidence silently dropped from pattern cards** (int vs str cluster-key mismatch): cards show `effects: 0 / confidence: LOW` while the sibling `correlation_stats.json` shows the cluster as notable. Verified end-to-end. | `report/pattern_card.py:300` vs `correlate/outcome_analyzer.py:192` | The flagship report contradicts its own supporting data. | + +--- + +## 4. High-severity findings (by domain) + +**Evidence / security** +- No tamper-evidence at rest: `extraction_records` is a plain writable SQLite table — no per-record digest, no hash-chaining, no signatures, no append-only storage (`provenance/schema.ts`). A NIST 800-86 / chain-of-custody review needs content-addressed, hash-chained, signed, RFC-3161-timestamped records on WORM media. +- LLM free-text harvested as evidence: `llm/prompts/process-query.ts:248-268` regexes 10-digit numbers and table names out of the model's *answer* and returns them as `document_references`. A hallucinated document number becomes cited evidence. +- Fabricated statistics fed to the LLM as ground truth: `tools/ask_process.ts:186-206` injects hardcoded "234 occurrences / 567 occurrences" patterns regardless of data, while the prompt says "Never make up statistics." +- Prompt injection: SAP/SFDC free-text (attacker-controllable order notes) is embedded into LLM prompts with no fencing or isolation (`ask_process.ts:379-398`). +- No SNC/TLS on RFC despite `SECURITY.md` claiming it; `.env.rfc` (live SAP creds) is **not** gitignored though the docs instruct `cp .env.rfc.example .env.rfc`. +- Server-side ReDoS: user-supplied regex compiled and run over document text in five adapters, with no complexity/timeout guard. + +**TypeScript architecture** +- **9 advertised "Evidence Infrastructure" tools are never registered** (`tools/index.ts` exposes 18 analysis + 9 governance = 27; the evidence stack — `query_provenance`, `run_extraction`, `detect_contradictions`, `validate_schema`, `analyze_reality_gaps`, `manage_finding`, `get_finding_summary`, `generate_handoff_packet`, `list_extraction_paths` — is implemented and tested but unreachable). ~36% of production code is dead from an MCP client's view, and CLAUDE.md's headline features do not exist in the shipped server. +- `console.log` on 24 code paths corrupts the stdio JSON-RPC transport (governance holds write raw lines to stdout mid-request). +- `createAdapter` hard-throws "not yet implemented" for `ecc_rfc` even though the ECC RFC adapter is a complete 7-file implementation — the "Live RFC connection" quickstart cannot work. +- SFDC 15/18-char IDs truncated to 10 chars (`field-mapper.ts:36-40`) → distinct opportunities collide on real orgs. +- Governance hold/approve workflow deadlocks: an approved operation is never actually executed; re-issuing the call creates a new hold. +- Reality-gap engine runs stop-word substring matchers inline; the real detectors exist but use an incompatible rule-type union and are never called. +- Retired Claude model default (`claude-3-sonnet-20240229`) → `ask_process` 404s out of the box. + +**Python engine** +- Fabricated "document text" invented on CSV import when no text file is supplied, merged into `consolidated_text` with no provenance marker and nondeterministically (builtin `hash()`). +- SALT "real SAP data" runs on synthesized delivery/GI/invoice events at flat +3/+4/+5 days (`salt_adapter.py:407`) — timing results are constant-latency artifacts under a "real data" banner. +- ML evaluation would mislead an auditor: `StandardScaler` fit on the full dataset before split (leakage); random split on time-ordered process data; features from completed traces encode the label; GradientBoosting "prediction intervals" are meaningless; `pickle` model load is an RCE vector. +- Demo reads the answer key: `analyze_sfdc.py` counts the generator's planted `_pattern_flags` and reports them as detections — an SAP-literate evaluator opening `opportunities.json` sees the tool "detecting" labels it was handed. +- Statistics: clusters tested against a baseline that includes the cluster; no multiple-comparison correction behind a "p < 0.05" footnote. +- `click` missing from `requirements.txt` → documented install path fails with `ModuleNotFoundError`. + +**Finding lifecycle / SQLite** +- Two contradictory state machines, two `FindingLifecycleDB` classes (the weaker `INSERT OR REPLACE`, history-truncating one is exported); non-atomic, unvalidated, TOCTOU-racy transitions with no CHECK constraint; the dedup UNIQUE index is void because SQLite treats NULLs as distinct. + +**Test / CI / reproducibility / hygiene** +- Coverage is **0% on exactly the security-critical paths**: the live RFC adapter, all three LLM providers, `policies/field-access.ts` and `policies/row-limits.ts`, and the Python evidence-ledger/report generators. Branch coverage 44.9% (TS) / 56% (Python). +- CI has broad version-matrix testing but **zero security tooling**: no CodeQL, no Dependabot, no `npm audit`/`pip-audit` gate (a critical-severity dev dependency sits unflagged), no secret scanning, no SBOM, no coverage floor, actions pinned by tag not SHA, Docker bases by floating tag, no image scan. +- Python deps are unpinned `>=` ranges with no lockfile — the "same seed → same report" reproducibility claim is undermined by dependency drift. +- Version identifiers disagree three ways (CHANGELOG 3.0.1 / package.json 1.0.1 / pyproject 0.1.1); zero git tags, so `release.yml` has never run. +- **Due-diligence embarrassments committed to the repo:** `agent1-work/` contains READMEs/CHANGELOGs/SECURITY.mds for **four unrelated projects** (restaurant, lex-intel, prompt-optimizer, dossier); `.agent3-staging/` and `.claude/context-checkpoint.md` are committed AI session scratch; a 54 MB generated `orders.json` and ~20 MB of Kaggle data (check redistribution rights) are in git history; `herb-nlp/` is an unrelated pipeline not in CI. +- **CLAUDE.md documents three directories that do not exist** (`src/evidence/`, `src/fi-co/`, `src/schema/`) and wrong env-var names (`SAP_HOST` vs `SAP_RFC_ASHOST`, `OLLAMA_BASE_URL` vs `OLLAMA_HOST`). + +--- + +## 5. Claims-vs-code: the overclaims a federal evaluator will flag + +These are credibility-damage items — reframe or fix before any technical evaluation. Honesty about a gap scores far better than discovered fiction. + +| Claim | Location | Reality | +|---|---|---| +| "FI/CO tables (financial accounting)" under **Data NOT Accessed** | `SECURITY.md:96` | Ships five FI/CO tools reading BKPF/BSEG. **Verified.** A security doc contradicting the feature list reads as stale or deceptive. | +| Audit log example shows `session_id`, `client_ip` | `SECURITY.md:301-305` | `audit-logger.ts` logs no user context; stdio has no client IP. Fabricated fields in a forensics security doc. | +| "Web Viewer (localhost only)" | `SECURITY.md:53,174` | Express binds all interfaces; compose publishes the port to the host; no auth. | +| "Default retention: 90 days" | `SECURITY.md:319` | Rotation is size-based (5×10MB); `LOG_DIR` env is ignored. | +| Architecture diagram: Pattern Engine → MCP Server over HTTP :3000; compose healthchecks `/health` | `SECURITY.md`, `docker-compose.yml` | The MCP server has **no HTTP listener at all**; the healthcheck can never pass. | +| "Replay hash confirms data is identical to source" | `README`, `manifest.ts` | Verification never contacts the source and the shipped script no-ops. **Verified.** | +| "Complete chain of custody" | `README.md:215` | No operator identity, no signatures. It is a chain of *integrity*, not *custody*. | +| SOC 2 / HIPAA / PCI mapping tables | `SECURITY.md:369-395` | No SOC 2 report exists; recast as "supports the customer's program," not product properties. | +| "NetSuite via API (all read-only)" | `README.md:818`, CLAUDE.md | **No NetSuite adapter exists** — only three SuiteQL query strings as metadata, with no client and no `executeExtraction` implementation. | +| "OCEL 2.0 export for PM4Py/Celonis" | CLAUDE.md, tool desc | O2C export is not valid OCEL 2.0; PM4Py import fails. | +| "NSA-grade" (aspirational) | positioning | `threat_model.md:457` excludes nation-state adversaries. Keep it out of the repo and the pitch. | + +--- + +## 6. New data sources to add (expansion research) + +The current adapter set is SAP ECC (RFC, real), S/4HANA OData (**explicit stub** — throws on every method), CSV (FI/CO only), Salesforce, SALT, BPI 2019, and synthetic. NetSuite is **vaporware**. Critically, the SAP forensic *blind spots* are exactly the sources a real government engagement demands: no change documents, no security audit log, no authorization-based SoD (the current `analyze_sod` is behavioral-only), no table logging, no transport logs, and no ACDOCA (so it cannot read the S/4 universal journal — and S/4 is where Army GFEBS and Navy ERP live). + +### Top 5, ranked by (federal-sales impact × feasibility) + +1. **USAspending.gov + SAM.gov Entity/Exclusions demo stack** — *very high impact, very high feasibility.* Free, keyless/free-key REST + CSV bulk. The missing **real-government-data demo**: Benford's law on contract actions, split purchases under thresholds, awards to excluded/debarred parties, shell-vendor clustering by shared address/officers, and three-way budget↔GL↔award reconciliation via account Files A/B/C. Cross-joining SAM exclusions against a customer's SAP `LFA1` vendor master is a live product feature, not just a demo. No FedRAMP, no credentials, no NDA to build it. (Note: FPDS-NG was decommissioned 2026-02-24 — build against the SAM.gov Contract Awards API.) +2. **SAP forensic pack: CDHDR/CDPOS change documents + SM20/RSAU security audit log + USR02/AGR_* authorization data.** Converts the product from process analytics into genuine forensics: field-level change evidence (the classic vendor-bank-account-change → payment → change-back demo), login/RFC/debug activity, and authorization-based SoD (what auditors actually mean). Extends the existing `ecc_rfc` pool + extraction registry. Reads are well-documented — `CHANGEDOCUMENT_READ`, `RSAU_API_GET_LOG_DATA` (RFC-released 2021), `RFC_READ_TABLE` with per-table `S_TABU_NAM` — and **Microsoft Sentinel's SAP connector is a proven reference architecture** to model on. Encode the gotchas: LFBK bank changes are delete+insert (`CHNGIND` I) not updates; CDPOS lives in cluster table CDCLS; SAL DB storage (`RSAU_BUF_DATA`) needs the API, not table reads. +3. **Deltek Costpoint adapter** — the SDVOSB's home turf. DCAA-compliance forensics (timecard fraud, cross-contract mischarging, indirect-rate manipulation) for GovCons is a paying niche with no incumbent process-mining tool and a shorter sales cycle than agency sales. Documented SOAP + REST/JWT integration; model on the SFDC adapter. +4. **Oracle EBS / U.S. Federal Financials** — the largest non-SAP federal ERP estate (DOI IBC, Treasury ARC, DOT Delphi, DoD DAI, Air Force DEAMS). `GL_JE_HEADERS`/`GL_JE_LINES`/`GL_BALANCES` + R12 `XLA_*` map almost 1:1 onto the existing BKPF/BSEG analytics. Combined with SAP, covers essentially every major DoD/civilian ERP — the "one forensics layer over all your ERPs" story. +5. **USSGL / GTAS conformance reference model** — not an adapter but a federal-accounting reference model like the existing O2C/P2P models. "Does this agency GL conform to USSGL account/attribute edits" is a uniquely federal differentiator that generic competitors cannot match off the shelf; public specs, open keyless Treasury Fiscal Data API. + +### Also worth doing +- **Kill the NetSuite vaporware** with a ~300-line SuiteQL-over-REST client (the three queries are already written) and implement the missing `executeExtraction` executor — this also makes `run_extraction` real for the first time. +- **Register the 9 unwired evidence tools** (prerequisite for most of the above; the extraction-registry is their natural home). +- **Finish or clearly label the S/4 OData stub** — GFEBS-adjacent buyers will ask about S/4 / ACDOCA specifically. +- **SIEM ingestion path** (Splunk/Sentinel/OCSF): agencies won't grant RFC access on day one but will let you read the Sentinel/Splunk workspace where SAP logs already land — a zero-new-attack-surface pitch matching the read-only ethos. OCSF has no ERP event class yet — emitting findings as OCSF Application-Activity events is a cheap differentiator for Amazon Security Lake shops. +- **More benchmark datasets** (cheap): BPI 2020 (T&E/expense claims), BPI 2018 (EU government subsidy payments), and the OCEL 2.0 SAP-IDES P2P/O2C sample logs (an OCEL *import* adapter also gives round-trip validation of the exporter). HuggingFace has essentially nothing relevant beyond SALT; 4TU.ResearchData is the real benchmark repository. + +--- + +## 7. Compliance posture and go-to-market positioning + +- **Position exclusively as self-hosted COTS inside the customer's ATO boundary (FISMA/RMF). Do not offer SaaS.** FedRAMP applies only to cloud service offerings; on-prem software is assessed inside the agency's own authorization. A FedRAMP authorization would cost years and mid-six figures for no benefit these buyers need. The read-only, air-gap-friendly design is the differentiator — make "air-gap mode" a *tested, verifiable* feature (a CI test asserting zero external endpoints; the cloud-LLM path behind a build/config flag customers can prove is disabled). +- **Controls the product can help customers satisfy (sellable):** AU-2/3/6/12 (it *is* an audit-analysis tool), AC-5 separation-of-duties evidence (`analyze_sod`), CM-3/CM-5 change evidence, AU-10-adjacent integrity evidence. +- **Controls the product itself fails today (blocking at Moderate+):** IA-2/AC-2/AC-3 (there is **no authentication anywhere** — the MCP server is single-user stdio; the viewer is an unauthenticated, no-TLS Express app binding all interfaces), AU-9/AU-9(3) (audit log is a plaintext file with no integrity protection — for a forensics tool this is also a courtroom-credibility problem), SC-8 (viewer plaintext HTTP), SC-13 (crypto is SHA-256 but not FIPS-*deliverable* on the Alpine images), SC-28 (no at-rest encryption), SI-2 (no vulnerability-management machinery), CM-6/CM-8 (no hardening baseline, no SBOM). +- **Evidence-grade (FRE 902(13)/(14)):** the handoff subsystem is ~70% of the way to a self-authentication story — but it needs (once the hashing is actually fixed) operator-identity + chain-of-custody metadata, a **digital signature** on the manifest (ideally RFC 3161 timestamped), and a 902(11) "declaration of a qualified person" certification template in the packet. Keep a hard wall between deterministic hash-verified extractions (evidence-grade) and ML/LLM narratives (investigative leads, never evidence) — proposed FRE 707 will subject machine-generated evidence to Rule 702 reliability standards. +- **FIPS 140-3:** FIPS 140-2 certs go Historical 2026-09-21. Node's bundled OpenSSL is not validated and Alpine/musl can't run FIPS mode. Offer a **FIPS deployment profile** (RHEL 9 / UBI9 base in FIPS mode, Node/Python linked to system OpenSSL — CMVP #4857/#4985). Claim "uses FIPS 140-3 validated modules when deployed on a FIPS-enabled OS," never "FIPS-validated product." +- **CMMC 2.0:** certifies organizations, not products. Start the SDVOSB's own 800-171 SSP + SPRS score now (Phase 2 C3PAO certification gate is 2026-11-10). The sellable framing: the tool generates evidence for a contractor's 800-171 3.3.x (audit) and 3.1.4 (SoD) assessment. +- **Section 508:** the viewer is in scope; an agency will request an ACR on VPAT 2.5 during market research. No ACR is a silent pre-award disqualifier. Current state: one `aria-` attribute, never tested. +- **SDVOSB mechanics:** SBA VetCert is mandatory and the hard prerequisite (do it first). VA Vets First (Rule of Two per *Kingdomware*; T4NG2/SPRUCE vehicles) is the strongest wedge and fits the FI/CO + SoD story. Fastest first dollars are subcontracts to primes doing ERP/financial-audit work — and those primes will ask for the exact artifact checklist below. + +--- + +## 8. Prioritized remediation roadmap + +### Tier 1 — Quick wins (days), mostly editing and CI YAML +1. **Rewrite `SECURITY.md` to match the code.** Fix every overclaim in §5; add an honest "the product does not yet provide user authentication; deploy behind…" section. *Removes the single fastest way to lose a technical evaluation.* +2. **Fix `docker-compose` drift** — remove the impossible HTTP healthcheck/port for the stdio server; bind the viewer to `127.0.0.1` by default. +3. **Purge the repo debris** — delete `agent1-work/`, `.agent3-staging/`, `.claude/context-checkpoint.md`, committed generated artifacts (`output/pattern_cards.md`, `pattern-engine/test_output/`); move `herb-nlp/` out; regenerate the 54 MB `orders.json` on demand (it's seeded) or use LFS; verify Kaggle redistribution rights. +4. **Regenerate CLAUDE.md** architecture/tools/env-vars from the actual tree (kill the three phantom directories and wrong env-var names). +5. **Turn on free scanning** — CodeQL (JS+Python), Dependabot (npm/pip/docker/actions), GitHub secret scanning + push protection, Trivy image scan; gate CI on `npm audit --omit=dev` and `pip-audit`; fix the dev-toolchain critical. +6. **Pin everything** — hash-pinned Python requirements (`pip-compile --generate-hashes`), digest-pinned Docker bases, `.nvmrc`/`.python-version`. +7. **Generate SBOMs in CI** and attach to releases; **sign releases** (cosign keyless + GitHub artifact attestations → SLSA Build L2). +8. **Reconcile the version number** to one value, tag `v3.0.1`, let `release.yml` run. +9. **Fix `.gitignore`** to exclude `.env.rfc` and `.env.*` (except `*.example`); fix the LICENSE copyright to a real legal entity. +10. **Retire "NSA-grade" and "complete chain of custody"** from all language. + +### Tier 2 — Correctness (weeks) — the items that make the product's claims true +11. **Fix the replay hash** (C-1/C-2): one canonical hash module for logger + manifest + verifier, with a regression test that a single mutated field changes the hash; make replay actually re-extract and recompute, not compare stored-to-stored. +12. **Fix the handoff packet** (C-3/C-4/C-11): ship the real verifier, build evidence from provenance records, detached-sign the manifest, add operator/custody metadata + a FRE 902 certification template, and escape shell/CSV/Markdown (formula-injection guard). +13. **Fix currency parsing and money representation** (C-5): shared parser, explicit per-source format, decimal-string/minor-unit amounts (floats also break round-amount detection). +14. **Fix the comparator contract** (C-6) and make "could not evaluate" a first-class result instead of a swallowed throw. +15. **Normalize SAP/SFDC identifiers at every match point** (C-7): ALPHA leading zeros, trim, no truncation of SFDC IDs. +16. **Fix conformance** (C-8): the `'bpi'` name check, the phantom optional-step check, the C/J/M case-folding; then implement real token replay or re-document honestly and drop the literature/precision claims. +17. **Fix OCEL export** (C-9) to valid OCEL 2.0 (arrays with `id`/`name`; keep falsy-but-present values; dedupe shared-delivery events) and validate against PM4Py in CI. +18. **Harden the finding lifecycle** (C-10): single `FindingLifecycleDB`, compare-and-swap transitions in one transaction, verbatim `restore()`, CHECK constraints, schema versioning. +19. **Register the 9 evidence tools**; remove `console.log` from server paths; fix the governance hold/approve deadlock; wire `ecc_rfc` through the registry; update the retired Claude model default. +20. **Fix the Python analytics** (C-12/C-13 + highs): non-reversible per-deployment HMAC redaction covering all emitted artifacts; the cluster-key type mismatch; stop fabricating texts/deliveries; make the SFDC demo detect (and score against `_pattern_flags` as held-out ground truth); cluster-vs-complement stats with Benjamini-Hochberg; ML leakage/temporal-split/interval fixes; add `click` to requirements. +21. **Add authentication + TLS** to every network surface; **tamper-evident (hash-chained, signed-checkpoint) audit logging** honoring `LOG_DIR`; apply the shareable redactor to the LLM path with a boundary-crossing warning when the provider is not Ollama. +22. **Add golden-output end-to-end tests** (`run` on fixed input → byte-comparable output across two invocations and two `PYTHONHASHSEED`s) and coverage floors on the policy/RFC/report paths. + +### Tier 3 — Strategic (months) — assurance and capture +23. **New data sources** per §6 — start with the USAspending/SAM.gov demo stack (this quarter) and the SAP forensic pack (CDHDR/CDPOS + SM20 + auth data). +24. **FIPS deployment profile** (UBI9, system OpenSSL, CI job running the suite in FIPS mode) before the 2026-09-21 FIPS 140-2 sunset. +25. **Multi-user RBAC + IdP** (OIDC/SAML) matching the 8-state finding lifecycle — enterprise/government buyers will not run approvals on the honor system. +26. **Write the three capture documents:** an 800-53 Rev 5 shared-responsibility control matrix, a hardening/secure-configuration + air-gap runbook (CM-6), and a data-location/at-rest guidance (SC-28); plus a VPAT 2.5 ACR for the viewer. +27. **Capture motion:** SBA VetCert; SAM/UEI + Section 889 reps; target VA Vets First primes; GSA MAS SIN 511210/54151S after commercial history; watch reauthorized SBIR (DHS/AFWERX) for the ML/pattern-discovery layer. + +--- + +## 9. One-paragraph summary for the owner + +The engineering *craft* here is real and rare — clean types, thousands of green tests, honest threat modeling, a read-only/on-prem/air-gap design that legitimately sidesteps FedRAMP and fits an SDVOSB capture motion. But the product currently *cannot deliver on its central promise*: the SHA-256 replay hash protects nothing (verified — tampered and untampered data hash identically), the "self-verifying" handoff packet ships a no-op verifier, currency is parsed 1000× wrong, most fraud comparators never actually run, and the security documentation contradicts the code in ways an evaluator falsifies in an hour. None of it needs a rewrite — the evidence pipeline is the right chassis — but the gap between the marketing and the machine is exactly what a competent government technical evaluation is built to find. Fix the documentation this week (free, and it protects everything else), make the evidence chain actually hold over the next few weeks, add the USAspending/SAM.gov demo and the SAP change-document/audit-log forensic pack to turn "process analytics" into genuine forensics, and drop "NSA-grade" for the defensible, provable claim: read-only, on-prem, hash-verified, FRE 902-aligned ERP forensics. diff --git a/mcp-server/package-lock.json b/mcp-server/package-lock.json index 21d97d6..5676fae 100644 --- a/mcp-server/package-lock.json +++ b/mcp-server/package-lock.json @@ -1,12 +1,12 @@ { "name": "transaction-forensics-mcp-server", - "version": "1.0.1", + "version": "3.0.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "transaction-forensics-mcp-server", - "version": "1.0.1", + "version": "3.0.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.29.0", diff --git a/mcp-server/package.json b/mcp-server/package.json index 928d6ba..befed71 100644 --- a/mcp-server/package.json +++ b/mcp-server/package.json @@ -1,6 +1,6 @@ { "name": "transaction-forensics-mcp-server", - "version": "1.0.1", + "version": "3.0.1", "description": "MCP server for Transaction Forensics - exposes tools for multi-system document analysis", "main": "dist/index.js", "type": "module", diff --git a/mcp-server/src/__tests__/parse-sap-number.test.ts b/mcp-server/src/__tests__/parse-sap-number.test.ts new file mode 100644 index 0000000..f8f6537 --- /dev/null +++ b/mcp-server/src/__tests__/parse-sap-number.test.ts @@ -0,0 +1,59 @@ +/** + * Tests for the shared SAP numeric parser. + * + * Locks in the fix for the 1000x currency-parsing bug: US and European + * thousands/decimal conventions must both parse correctly. + */ + +import { describe, it, expect } from '@jest/globals'; + +import { parseSAPNumber } from '../adapters/shared/parse-sap-number.js'; + +describe('parseSAPNumber', () => { + it('parses European format (1.234,56 -> 1234.56)', () => { + expect(parseSAPNumber('1.234,56')).toBeCloseTo(1234.56, 2); + }); + + it('parses US/standard format (1,234.56 -> 1234.56)', () => { + expect(parseSAPNumber('1,234.56')).toBeCloseTo(1234.56, 2); + }); + + it('parses a plain decimal (1234.56 -> 1234.56)', () => { + expect(parseSAPNumber('1234.56')).toBeCloseTo(1234.56, 2); + }); + + it('parses multi-group European (1.234.567,89 -> 1234567.89)', () => { + expect(parseSAPNumber('1.234.567,89')).toBeCloseTo(1234567.89, 2); + }); + + it('parses multi-group US (1,234,567.89 -> 1234567.89)', () => { + expect(parseSAPNumber('1,234,567.89')).toBeCloseTo(1234567.89, 2); + }); + + it('handles trailing-minus negatives (1234.56- -> -1234.56)', () => { + expect(parseSAPNumber('1234.56-')).toBeCloseTo(-1234.56, 2); + }); + + it('handles parenthesized negatives ((1234.56) -> -1234.56)', () => { + expect(parseSAPNumber('(1234.56)')).toBeCloseTo(-1234.56, 2); + }); + + it('strips a leading ISO currency code (EUR 1.234,56 -> 1234.56)', () => { + expect(parseSAPNumber('EUR 1.234,56')).toBeCloseTo(1234.56, 2); + }); + + it('passes numeric input through unchanged', () => { + expect(parseSAPNumber(4200.5)).toBe(4200.5); + }); + + it('treats empty/blank as 0', () => { + expect(parseSAPNumber('')).toBe(0); + expect(parseSAPNumber(' ')).toBe(0); + }); + + it('does NOT collapse a both-separator amount to ~1.2 (the old bug)', () => { + // The regression this test guards: 1.234,56 and 1,234.56 must not become 1.234. + expect(parseSAPNumber('1.234,56')).toBeGreaterThan(1000); + expect(parseSAPNumber('1,234.56')).toBeGreaterThan(1000); + }); +}); diff --git a/mcp-server/src/__tests__/provenance-replay-hash-regression.test.ts b/mcp-server/src/__tests__/provenance-replay-hash-regression.test.ts new file mode 100644 index 0000000..47de649 --- /dev/null +++ b/mcp-server/src/__tests__/provenance-replay-hash-regression.test.ts @@ -0,0 +1,76 @@ +/** + * Regression tests for the replay-hash coverage bug. + * + * Background: `ProvenanceLogger.computeReplayHash` previously passed + * `Object.keys(result)` as JSON.stringify's *replacer array*, so an + * array-of-rows result serialized as `[{},{}]` — the stored hash was a + * function of row count only and did not change when field values were + * tampered with. These tests lock in that the hash now covers every leaf + * value and that the logger and the standalone replay module agree. + */ + +import { describe, it, expect } from '@jest/globals'; +import { createHash } from 'node:crypto'; + +import { canonicalStringify, computeReplayHash } from '../provenance/replay.js'; + +/** Mirror of ProvenanceLogger's private hash so we can assert agreement. */ +function loggerReplayHash(result: unknown): string { + return createHash('sha256').update(canonicalStringify(result)).digest('hex'); +} + +describe('replay hash coverage (regression)', () => { + it('changes when a single nested field is tampered with', () => { + const real = [ + { vbeln: '0000012345', netwr: '1000.00' }, + { vbeln: '0000012346', netwr: '2000.00' }, + ]; + const tampered = [ + { vbeln: '0000012345', netwr: '9999999.00' }, + { vbeln: '0000012346', netwr: '2000.00' }, + ]; + + expect(loggerReplayHash(real)).not.toBe(loggerReplayHash(tampered)); + }); + + it('is invariant to object key ordering', () => { + const a = [{ vbeln: '1', netwr: '10', erdat: '20260101' }]; + const b = [{ erdat: '20260101', netwr: '10', vbeln: '1' }]; + + expect(loggerReplayHash(a)).toBe(loggerReplayHash(b)); + }); + + it('distinguishes row count from row content', () => { + // The old bug made these collide (both serialized to a 2-element array of {}). + const twoRealRows = [ + { doc: 'A', amount: '1' }, + { doc: 'B', amount: '2' }, + ]; + const twoOtherRows = [ + { doc: 'X', amount: '9' }, + { doc: 'Y', amount: '8' }, + ]; + + expect(loggerReplayHash(twoRealRows)).not.toBe(loggerReplayHash(twoOtherRows)); + }); + + it('canonicalizes scalar and object results without throwing', () => { + expect(() => loggerReplayHash('scalar')).not.toThrow(); + expect(() => loggerReplayHash({ nested: { a: 1, b: [1, 2, 3] } })).not.toThrow(); + expect(loggerReplayHash(42)).toBe(loggerReplayHash(42)); + }); + + it('agrees with the standalone row hasher on flat string rows', () => { + // computeReplayHash(rows) uses canonicalizeRow (tuple form); this test just + // asserts the standalone hasher is itself sensitive to field tampering, so + // both evidence paths detect the same mutations. + const rows = [{ a: '1', b: '2' }]; + const mutated = [{ a: '1', b: '3' }]; + expect(computeReplayHash(rows)).not.toBe(computeReplayHash(mutated)); + }); + + it('canonicalStringify normalizes null/undefined to empty string', () => { + expect(canonicalStringify({ a: null })).toBe(canonicalStringify({ a: '' })); + expect(canonicalStringify({ a: undefined })).toBe(canonicalStringify({ a: '' })); + }); +}); diff --git a/mcp-server/src/adapters/csv/index.ts b/mcp-server/src/adapters/csv/index.ts index 083b1b2..a1d14b7 100644 --- a/mcp-server/src/adapters/csv/index.ts +++ b/mcp-server/src/adapters/csv/index.ts @@ -18,6 +18,7 @@ */ import { BaseDataAdapter, registerAdapter } from '../adapter-interface.js'; +import { parseSAPNumber } from '../shared/parse-sap-number.js'; import { SearchDocTextParams, SearchResult, @@ -105,45 +106,9 @@ function parseSAPDate(value: string): string { * SAP can use comma as decimal separator (1.234,56) or period (1,234.56) */ function parseSAPAmount(value: string): number { - if (!value || value.trim() === '') return 0; - - let trimmed = value.trim(); - - // Remove currency symbols and whitespace - trimmed = trimmed.replace(/[A-Z]{3}\s*/g, '').trim(); - - // Handle negative amounts indicated by trailing minus or parentheses - let negative = false; - if (trimmed.endsWith('-')) { - negative = true; - trimmed = trimmed.slice(0, -1); - } - if (trimmed.startsWith('(') && trimmed.endsWith(')')) { - negative = true; - trimmed = trimmed.slice(1, -1); - } - if (trimmed.startsWith('-')) { - negative = true; - trimmed = trimmed.slice(1); - } - - // Detect European vs US number format - // European: 1.234,56 (period as thousands, comma as decimal) - // US/Standard: 1,234.56 (comma as thousands, period as decimal) - const lastComma = trimmed.lastIndexOf(','); - const lastPeriod = trimmed.lastIndexOf('.'); - - let parsed: number; - if (lastComma > lastPeriod) { - // European format: comma is decimal separator - parsed = parseFloat(trimmed.replace(/\./g, '').replace(',', '.')); - } else { - // US/Standard format: period is decimal separator - parsed = parseFloat(trimmed.replace(/,/g, '')); - } - - if (isNaN(parsed)) return 0; - return negative ? -parsed : parsed; + // Shared last-separator-wins parser (handles US 1,234.56 and EU 1.234,56, + // trailing-minus, parentheses, and ISO currency codes). + return parseSAPNumber(value); } /** diff --git a/mcp-server/src/adapters/ecc_rfc/mappers.ts b/mcp-server/src/adapters/ecc_rfc/mappers.ts index 6b3474b..895e244 100644 --- a/mcp-server/src/adapters/ecc_rfc/mappers.ts +++ b/mcp-server/src/adapters/ecc_rfc/mappers.ts @@ -17,6 +17,7 @@ import type { MasterStub, DocTextResult, } from '../../types/sap.js'; +import { parseSAPNumber } from '../shared/parse-sap-number.js'; import type { SalesDocHeader as RFCSalesDocHeader, @@ -77,22 +78,13 @@ export function mapSAPTime(sapTime: string): string { } /** - * Parse SAP number string to JavaScript number - * Handles SAP's decimal format (comma vs period) and negative notation + * Parse SAP number string to JavaScript number. + * Delegates to the shared last-separator-wins parser so US (1,234.56) and + * European (1.234,56) formats are both handled correctly (the previous blind + * comma->period replace collapsed both to 1.234). */ export function mapSAPNumber(sapNum: string | number): number { - if (typeof sapNum === 'number') { - return sapNum; - } - if (!sapNum) { - return 0; - } - // SAP sometimes uses comma as decimal separator - const normalized = sapNum.replace(/,/g, '.').replace(/\s/g, ''); - // Handle negative notation (trailing -) - const isNegative = normalized.endsWith('-'); - const numStr = isNegative ? '-' + normalized.slice(0, -1) : normalized; - return parseFloat(numStr) || 0; + return parseSAPNumber(sapNum); } /** diff --git a/mcp-server/src/adapters/shared/parse-sap-number.ts b/mcp-server/src/adapters/shared/parse-sap-number.ts new file mode 100644 index 0000000..08d9f5c --- /dev/null +++ b/mcp-server/src/adapters/shared/parse-sap-number.ts @@ -0,0 +1,69 @@ +/** + * Shared SAP numeric parser. + * + * SAP amounts arrive in locale-dependent forms depending on the extracting + * user's profile: + * - US/standard: 1,234.56 (comma = thousands, period = decimal) + * - European: 1.234,56 (period = thousands, comma = decimal) + * plus SAP's trailing-minus negatives (`1234.56-`) and occasional + * parenthesized negatives / leading ISO currency codes. + * + * The previous `ecc_rfc/mappers.ts` implementation did a blind + * `replace(/,/g, '.')`, which turned BOTH `1.234,56` and `1,234.56` into + * `1.234` — a silent 1000x (or larger) error feeding every FI/CO threshold. + * This parser uses a last-separator-wins rule (the right-most of `.` / `,` is + * the decimal separator) so both conventions parse correctly. + * + * Irreducible ambiguity: a lone grouping like `1,234` (no decimal part) could + * mean 1234 (US thousands) or 1.234 (EU decimal). Last-separator-wins treats it + * as a decimal — matching the historical CSV-adapter behavior. Callers that + * know their source's locale should pass an explicit format in a future change; + * see the roadmap in docs/GOVERNMENT-READINESS-REVIEW.md. + */ +export function parseSAPNumber(value: string | number): number { + if (typeof value === 'number') { + return value; + } + if (!value || value.trim() === '') { + return 0; + } + + let trimmed = value.trim(); + + // Strip leading/trailing ISO currency codes (e.g. "EUR 1.234,56"). + trimmed = trimmed.replace(/[A-Z]{3}\s*/g, '').trim(); + + // Normalize negative notations: trailing minus, parentheses, leading minus. + let negative = false; + if (trimmed.endsWith('-')) { + negative = true; + trimmed = trimmed.slice(0, -1); + } + if (trimmed.startsWith('(') && trimmed.endsWith(')')) { + negative = true; + trimmed = trimmed.slice(1, -1); + } + if (trimmed.startsWith('-')) { + negative = true; + trimmed = trimmed.slice(1); + } + + // Last-separator-wins: whichever of ',' / '.' appears right-most is the + // decimal separator; the other is grouping and is removed. + const lastComma = trimmed.lastIndexOf(','); + const lastPeriod = trimmed.lastIndexOf('.'); + + let parsed: number; + if (lastComma > lastPeriod) { + // European: comma is the decimal separator. + parsed = parseFloat(trimmed.replace(/\./g, '').replace(',', '.')); + } else { + // US/standard (or no separators): period is the decimal separator. + parsed = parseFloat(trimmed.replace(/,/g, '')); + } + + if (isNaN(parsed)) { + return 0; + } + return negative ? -parsed : parsed; +} diff --git a/mcp-server/src/provenance/logger.ts b/mcp-server/src/provenance/logger.ts index 4f37755..a2c9cb1 100644 --- a/mcp-server/src/provenance/logger.ts +++ b/mcp-server/src/provenance/logger.ts @@ -18,6 +18,7 @@ import { createHash, randomUUID } from 'node:crypto'; import type { IDataAdapter } from '../adapters/adapter-interface.js'; import type { ExtractionRecord, SystemType } from './types.js'; +import { canonicalStringify } from './replay.js'; /** * Minimal interface for the provenance database. @@ -319,23 +320,23 @@ export class ProvenanceLogger { * Same inputs always produce the same hash. */ private computeQueryHash(methodName: string, params: Record): string { - const sorted = Object.entries(params) - .sort(([a], [b]) => a.localeCompare(b)) - .map(([k, v]) => [k, String(v ?? '')]); - - const canonical = JSON.stringify({ method: methodName, params: sorted }); + // Canonicalize recursively so object/array params hash by content rather + // than collapsing to "[object Object]" via String(). + const canonical = canonicalStringify({ method: methodName, params }); return createHash('sha256').update(canonical).digest('hex'); } /** * Deterministic hash of a result value. - * Same result always produces the same hash. + * + * Uses the shared canonical serializer so the hash covers every leaf value + * at every depth. The prior implementation passed `Object.keys(result)` as + * JSON.stringify's replacer array, which serialized array-of-row results as + * `[{},{}]` — making the hash a function of row count only and blind to any + * data tampering. */ private computeReplayHash(result: unknown): string { - const canonical = JSON.stringify( - result, - Object.keys(typeof result === 'object' && result !== null ? result : {}).sort() - ); + const canonical = canonicalStringify(result); return createHash('sha256').update(canonical).digest('hex'); } } diff --git a/mcp-server/src/provenance/replay.ts b/mcp-server/src/provenance/replay.ts index eacdb39..d0df84a 100644 --- a/mcp-server/src/provenance/replay.ts +++ b/mcp-server/src/provenance/replay.ts @@ -73,6 +73,47 @@ export function verifyReplayHash( return { match: expectedHash === currentHash, currentHash }; } +/** + * Deterministic canonical serialization of an arbitrary JSON-like value. + * + * Unlike `JSON.stringify`, this recursively sorts object keys at every depth, + * so two logically-equal values serialize identically regardless of key order, + * and — critically — the serialization actually covers every leaf value. (The + * previous per-record hasher passed `Object.keys(result)` as JSON.stringify's + * replacer array, which for an array-of-rows collapsed every row to `{}`, so + * the hash was a function of row count only and did not detect tampering.) + * + * Canonicalization rules (matching this module's header contract): + * - object keys sorted alphabetically at all depths + * - null / undefined normalized to "" + * - string leaves trimmed of leading/trailing whitespace + * - arrays preserve order (order is evidentiary) + */ +export function canonicalStringify(value: unknown): string { + return JSON.stringify(canonicalize(value)); +} + +function canonicalize(value: unknown): unknown { + if (value === null || value === undefined) { + return ''; + } + if (typeof value === 'string') { + return value.trim(); + } + if (Array.isArray(value)) { + return value.map(canonicalize); + } + if (typeof value === 'object') { + const out: Record = {}; + for (const key of Object.keys(value as Record).sort()) { + out[key] = canonicalize((value as Record)[key]); + } + return out; + } + // numbers, booleans — leave as-is (stable under JSON.stringify) + return value; +} + // --------------------------------------------------------------------------- // Internal helpers // --------------------------------------------------------------------------- diff --git a/output/pattern_cards.md b/output/pattern_cards.md deleted file mode 100644 index ba3821f..0000000 --- a/output/pattern_cards.md +++ /dev/null @@ -1,259 +0,0 @@ -# SAP Workflow Mining Pattern Report - -**Generated**: 2025-12-28T12:59:16.507553Z -**Version**: 0.1.0 -**Random Seed**: 42 - -## Summary - -- **Total Patterns**: 6 -- **Notable Patterns**: 0 -- **Total Documents**: 3018 -- **Average Confidence**: 40% - -## Other Patterns - -## Customer Request / Request / Customer - -**ID**: PAT-83AF9F88 -**Confidence**: 40% -**Sample Size**: 412 documents - -### Description -Documents in this cluster frequently contain "customer request", "request", "customer". No statistically significant timing differences from baseline. Based on analysis of 412 documents. - -### Characteristic Phrases -- customer request -- request -- customer -- expedite customer request -- expedite customer - -### Caveats -- Observational analysis only; correlation does not imply causation. -- Patterns based on text similarity; may not capture all relevant factors. -- No statistically significant effects detected. - -### Evidence Summary - -- **Documents**: 412 -- **Source Files**: 6 - -**Row Counts:** -- total_documents: 10,000 -- cluster_documents: 412 - -**Reproducibility:** -- Seed: 42 -- Algorithm: kmeans -- Embedding: tfidf -- Timestamp: 2025-12-28T12:59:16.445872Z - ---- - -## Hold / Credit / Credit Hold - -**ID**: PAT-EBE92C4E -**Confidence**: 40% -**Sample Size**: 211 documents - -### Description -Documents in this cluster frequently contain "hold", "credit", "credit hold". No statistically significant timing differences from baseline. Based on analysis of 211 documents. - -### Characteristic Phrases -- hold -- credit -- credit hold -- hold expedite -- hold credit - -### Caveats -- Observational analysis only; correlation does not imply causation. -- Patterns based on text similarity; may not capture all relevant factors. -- No statistically significant effects detected. - -### Evidence Summary - -- **Documents**: 211 -- **Source Files**: 6 - -**Row Counts:** -- total_documents: 10,000 -- cluster_documents: 211 - -**Reproducibility:** -- Seed: 42 -- Algorithm: kmeans -- Embedding: tfidf -- Timestamp: 2025-12-28T12:59:16.452729Z - ---- - -## Needs Friday / Friday / Needs - -**ID**: PAT-60E4E555 -**Confidence**: 40% -**Sample Size**: 370 documents - -### Description -Documents in this cluster frequently contain "needs friday", "friday", "needs". No statistically significant timing differences from baseline. Based on analysis of 370 documents. - -### Characteristic Phrases -- needs friday -- friday -- needs -- customer needs friday -- customer needs - -### Caveats -- Observational analysis only; correlation does not imply causation. -- Patterns based on text similarity; may not capture all relevant factors. -- No statistically significant effects detected. - -### Evidence Summary - -- **Documents**: 370 -- **Source Files**: 6 - -**Row Counts:** -- total_documents: 10,000 -- cluster_documents: 370 - -**Reproducibility:** -- Seed: 42 -- Algorithm: kmeans -- Embedding: tfidf -- Timestamp: 2025-12-28T12:59:16.459473Z - ---- - -## Ref / Partial / Ship - -**ID**: PAT-67AFBFAC -**Confidence**: 40% -**Sample Size**: 1302 documents - -### Description -Documents in this cluster frequently contain "ref", "partial", "ship". No statistically significant timing differences from baseline. Based on analysis of 1302 documents. - -### Characteristic Phrases -- ref -- partial -- ship -- stock -- order - -### Caveats -- Observational analysis only; correlation does not imply causation. -- Patterns based on text similarity; may not capture all relevant factors. -- No statistically significant effects detected. - -### Evidence Summary - -- **Documents**: 1302 -- **Source Files**: 6 - -**Row Counts:** -- total_documents: 10,000 -- cluster_documents: 1,302 - -**Reproducibility:** -- Seed: 42 -- Algorithm: kmeans -- Embedding: tfidf -- Timestamp: 2025-12-28T12:59:16.492388Z - ---- - -## Expedite / Expedite Expedite / Expedite Ref - -**ID**: PAT-61AF9396 -**Confidence**: 40% -**Sample Size**: 354 documents - -### Description -Documents in this cluster frequently contain "expedite", "expedite expedite", "expedite ref". No statistically significant timing differences from baseline. Based on analysis of 354 documents. - -### Characteristic Phrases -- expedite -- expedite expedite -- expedite ref -- rush expedite -- ref - -### Caveats -- Observational analysis only; correlation does not imply causation. -- Patterns based on text similarity; may not capture all relevant factors. -- No statistically significant effects detected. - -### Evidence Summary - -- **Documents**: 354 -- **Source Files**: 6 - -**Row Counts:** -- total_documents: 10,000 -- cluster_documents: 354 - -**Reproducibility:** -- Seed: 42 -- Algorithm: kmeans -- Embedding: tfidf -- Timestamp: 2025-12-28T12:59:16.498804Z - ---- - -## Mgmt / Mgmt Approved / Approved - -**ID**: PAT-2688648C -**Confidence**: 40% -**Sample Size**: 369 documents - -### Description -Documents in this cluster frequently contain "mgmt", "mgmt approved", "approved". No statistically significant timing differences from baseline. Based on analysis of 369 documents. - -### Characteristic Phrases -- mgmt -- mgmt approved -- approved -- expedite mgmt -- expedite mgmt approved - -### Caveats -- Observational analysis only; correlation does not imply causation. -- Patterns based on text similarity; may not capture all relevant factors. -- No statistically significant effects detected. - -### Evidence Summary - -- **Documents**: 369 -- **Source Files**: 6 - -**Row Counts:** -- total_documents: 10,000 -- cluster_documents: 369 - -**Reproducibility:** -- Seed: 42 -- Algorithm: kmeans -- Embedding: tfidf -- Timestamp: 2025-12-28T12:59:16.504367Z - ---- - -## Appendix: Reproducibility - -To reproduce this analysis: - -```bash -python -m pattern_engine run --seed 42 \ - --input-dir ./data --output-dir ./output -``` - -### Parameters Used - -- Clustering Algorithm: kmeans -- Embedding Model: tfidf -- Number of Clusters: 6 -- Minimum Cluster Size: 5 -- Delay Threshold: 7 days \ No newline at end of file diff --git a/pattern-engine/pyproject.toml b/pattern-engine/pyproject.toml index 95b7422..ce6d1fc 100644 --- a/pattern-engine/pyproject.toml +++ b/pattern-engine/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "pattern-engine" -version = "0.1.1" +version = "3.0.1" description = "Transaction Forensics Pattern Engine - discovers text patterns and correlates them to outcomes" readme = "README.md" license = {text = "MIT"} diff --git a/pattern-engine/src/ingest/csv_loader.py b/pattern-engine/src/ingest/csv_loader.py index 6e2e9c3..330e995 100644 --- a/pattern-engine/src/ingest/csv_loader.py +++ b/pattern-engine/src/ingest/csv_loader.py @@ -30,6 +30,32 @@ logger = logging.getLogger(__name__) +def _parse_sap_float(value: str) -> float: + """Parse a SAP amount string using last-separator-wins. + + SAP exports use locale-dependent grouping/decimal separators: + - US/standard: 1,234.56 (comma thousands, period decimal) + - European: 1.234,56 (period thousands, comma decimal) + The right-most of ',' / '.' is treated as the decimal separator; the other + is grouping and removed. Raises ValueError on non-numeric input (caller + falls back to the raw value). + + Note: a lone grouping like '1,234' (no decimal part) is irreducibly + ambiguous and is treated as a decimal (1.234), matching last-separator-wins; + callers that know their source locale should normalize upstream. + """ + text = value.strip() + last_comma = text.rfind(',') + last_period = text.rfind('.') + if last_comma > last_period: + # European: comma is the decimal separator. + text = text.replace('.', '').replace(',', '.') + else: + # US/standard (or no separators): period is the decimal separator. + text = text.replace(',', '') + return float(text) + + # ============================================================================= # Field Mappings: CSV column headers -> Internal field names # ============================================================================= @@ -644,12 +670,10 @@ def _clean_value(self, value: Any) -> Any: if value.isdigit() or (value.startswith('-') and value[1:].isdigit()): return int(value) - # Check for float (handle European format with comma decimal) - if ',' in value and '.' not in value: - value = value.replace(',', '.') - - float_val = float(value.replace(',', '')) - return float_val + # Float: last-separator-wins so US (1,234.56) and European + # (1.234,56) both parse correctly. The previous logic mishandled + # 1.234,56 -> 1.23456 (period kept as decimal, comma stripped). + return _parse_sap_float(value) except (ValueError, AttributeError): pass diff --git a/pattern-engine/test_output/clustering_summary.json b/pattern-engine/test_output/clustering_summary.json deleted file mode 100644 index b902907..0000000 --- a/pattern-engine/test_output/clustering_summary.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "metadata": { - "generated_at": "2025-12-27T23:53:08.579610Z", - "seed": 42 - }, - "n_documents": 10000, - "n_clusters": 8, - "silhouette_score": 0.08109978050222698, - "cluster_info": { - "0": { - "n_documents": "347", - "avg_text_length": 22.953890489913544, - "percentage": 11.912118091314795 - }, - "1": { - "n_documents": "360", - "avg_text_length": 33.205555555555556, - "percentage": 12.358393408856848 - }, - "2": { - "n_documents": "141", - "avg_text_length": 21.914893617021278, - "percentage": 4.840370751802266 - }, - "3": { - "n_documents": "819", - "avg_text_length": 15.145299145299145, - "percentage": 28.11534500514933 - }, - "4": { - "n_documents": "402", - "avg_text_length": 22.35323383084577, - "percentage": 13.80020597322348 - }, - "5": { - "n_documents": "195", - "avg_text_length": 24.066666666666666, - "percentage": 6.694129763130793 - }, - "6": { - "n_documents": "361", - "avg_text_length": 28.68698060941828, - "percentage": 12.392722279437006 - }, - "7": { - "n_documents": "288", - "avg_text_length": 16.82986111111111, - "percentage": 9.88671472708548 - } - }, - "parameters": { - "embedding_model": "tfidf", - "clustering_algorithm": "kmeans", - "n_clusters": 8, - "min_cluster_size": 5, - "random_seed": 42 - } -} \ No newline at end of file diff --git a/pattern-engine/test_output/correlation_stats.json b/pattern-engine/test_output/correlation_stats.json deleted file mode 100644 index d9291e8..0000000 --- a/pattern-engine/test_output/correlation_stats.json +++ /dev/null @@ -1,930 +0,0 @@ -{ - "metadata": { - "generated_at": "2025-12-27T23:53:08.579778Z", - "seed": 42 - }, - "baseline": { - "order_to_delivery_days": { - "mean": 7.330770030136132, - "std": 6.306257174129212, - "median": 5.0, - "n": 9623, - "min": 1.0, - "max": 36.0 - }, - "delivery_delay_days": { - "mean": -2.192559492881638, - "std": 6.918432232686225, - "median": -4.0, - "n": 9623, - "min": -13.0, - "max": 29.0 - }, - "invoice_lag_days": { - "mean": 2.9398682932095435, - "std": 3.0556189262026363, - "median": 2.0, - "n": 9263, - "min": 1.0, - "max": 34.0 - }, - "order_to_invoice_days": { - "mean": 10.27302169923351, - "std": 6.998723764050458, - "median": 8.0, - "n": 9263, - "min": 2.0, - "max": 48.0 - }, - "delay_probability": { - "value": 0.10506079185285254, - "n_delayed": 1011, - "n_total": 9623 - }, - "partial_delivery_rate": { - "value": 0.25875506598773773, - "n_partial": 2490, - "n_total": 9623 - }, - "return_rate": { - "value": 0.0122, - "n_returns": 122, - "n_total": 10000 - } - }, - "summary": { - "n_clusters_analyzed": 8, - "n_notable_clusters": 5, - "notable_cluster_ids": [ - 1, - 2, - 3, - 5, - 7 - ], - "baseline_metrics": [ - "order_to_delivery_days", - "delivery_delay_days", - "invoice_lag_days", - "order_to_invoice_days", - "delay_probability", - "partial_delivery_rate", - "return_rate" - ] - }, - "parameters": { - "delay_threshold_days": 7, - "confidence_level": 0.95, - "min_sample_size": 5 - }, - "clusters": { - "0": { - "cluster_id": 0, - "n_documents": 347, - "effect_sizes": { - "order_to_delivery_days": { - "metric": "order_to_delivery_days", - "cluster_value": 9.954954954954955, - "baseline_value": 7.330770030136132, - "difference": 2.624184924818823, - "effect_size": 0.40872741872081975, - "effect_interpretation": "small", - "ci_lower": 1.6356411210324742, - "ci_upper": 3.6127287286051715, - "p_value": 2.4298903106133527e-13, - "is_significant": true, - "n_cluster": 333, - "n_baseline": 9623 - }, - "delivery_delay_days": { - "metric": "delivery_delay_days", - "cluster_value": 0.26126126126126126, - "baseline_value": -2.192559492881638, - "difference": 2.453820754142899, - "effect_size": 0.3497713112008114, - "effect_interpretation": "small", - "ci_lower": 1.4343479274554372, - "ci_upper": 3.473293580830361, - "p_value": 3.640101745188855e-10, - "is_significant": true, - "n_cluster": 333, - "n_baseline": 9623 - }, - "invoice_lag_days": { - "metric": "invoice_lag_days", - "cluster_value": 3.0123839009287927, - "baseline_value": 2.9398682932095435, - "difference": 0.07251560771924925, - "effect_size": 0.023750807396526824, - "effect_interpretation": "negligible", - "ci_lower": -0.2586636519690327, - "ci_upper": 0.4036948674075312, - "p_value": 0.6747861904580895, - "is_significant": false, - "n_cluster": 323, - "n_baseline": 9263 - }, - "order_to_invoice_days": { - "metric": "order_to_invoice_days", - "cluster_value": 13.030959752321982, - "baseline_value": 10.27302169923351, - "difference": 2.7579380530884716, - "effect_size": 0.38837575427316723, - "effect_interpretation": "small", - "ci_lower": 1.7021581292411898, - "ci_upper": 3.813717976935753, - "p_value": 7.242737362469998e-12, - "is_significant": true, - "n_cluster": 323, - "n_baseline": 9263 - }, - "delay_probability": { - "metric": "delay_probability", - "cluster_value": 0.2552552552552553, - "baseline_value": 0.10506079185285254, - "difference": 0.15019446340240272, - "effect_size": 0.39910650018811267, - "effect_interpretation": "small", - "ci_lower": 0.10296618131246851, - "ci_upper": 0.19742274549233693, - "p_value": 0.0, - "is_significant": true, - "n_cluster": 333, - "n_baseline": 9623 - }, - "partial_delivery_rate": { - "metric": "partial_delivery_rate", - "cluster_value": 0.3063063063063063, - "baseline_value": 0.25875506598773773, - "difference": 0.047551240318568555, - "effect_size": 0.10569912033422502, - "effect_interpretation": "negligible", - "ci_lower": -0.0027254787402959946, - "ci_upper": 0.0978279593774331, - "p_value": 0.051889511484640716, - "is_significant": false, - "n_cluster": 333, - "n_baseline": 9623 - }, - "return_rate": { - "metric": "return_rate", - "cluster_value": 0.05475504322766571, - "baseline_value": 0.0122, - "difference": 0.042555043227665706, - "effect_size": 0.2510166807448561, - "effect_interpretation": "small", - "ci_lower": 0.018521654324761654, - "ci_upper": 0.06658843213056975, - "p_value": 1.794919768371983e-11, - "is_significant": true, - "n_cluster": 347, - "n_baseline": 10000 - } - }, - "summary": "Shows small higher order to delivery days, small higher delivery delay days, small higher order to invoice days, small higher delay probability, small higher return rate", - "is_notable": false - }, - "1": { - "cluster_id": 1, - "n_documents": 360, - "effect_sizes": { - "order_to_delivery_days": { - "metric": "order_to_delivery_days", - "cluster_value": 10.585014409221902, - "baseline_value": 7.330770030136132, - "difference": 3.25424437908577, - "effect_size": 0.5046699168072488, - "effect_interpretation": "medium", - "ci_lower": 2.237365209728071, - "ci_upper": 4.271123548443469, - "p_value": 3.0835142931730443e-20, - "is_significant": true, - "n_cluster": 347, - "n_baseline": 9623 - }, - "delivery_delay_days": { - "metric": "delivery_delay_days", - "cluster_value": 1.1181556195965419, - "baseline_value": -2.192559492881638, - "difference": 3.3107151124781797, - "effect_size": 0.4691460236741203, - "effect_interpretation": "small", - "ci_lower": 2.2306971533336437, - "ci_upper": 4.390733071622716, - "p_value": 1.0369329418886571e-17, - "is_significant": true, - "n_cluster": 347, - "n_baseline": 9623 - }, - "invoice_lag_days": { - "metric": "invoice_lag_days", - "cluster_value": 3.2058823529411766, - "baseline_value": 2.9398682932095435, - "difference": 0.26601405973163317, - "effect_size": 0.08681536464116006, - "effect_interpretation": "negligible", - "ci_lower": -0.08905342105582503, - "ci_upper": 0.6210815405190914, - "p_value": 0.11593659984388965, - "is_significant": false, - "n_cluster": 340, - "n_baseline": 9263 - }, - "order_to_invoice_days": { - "metric": "order_to_invoice_days", - "cluster_value": 13.688235294117646, - "baseline_value": 10.27302169923351, - "difference": 3.4152135948841362, - "effect_size": 0.4780037742043462, - "effect_interpretation": "small", - "ci_lower": 2.3039596104560567, - "ci_upper": 4.526467579312216, - "p_value": 5.647358955827827e-18, - "is_significant": true, - "n_cluster": 340, - "n_baseline": 9263 - }, - "delay_probability": { - "metric": "delay_probability", - "cluster_value": 0.2910662824207493, - "baseline_value": 0.10506079185285254, - "difference": 0.18600549056789673, - "effect_size": 0.4795139922113627, - "effect_interpretation": "small", - "ci_lower": 0.137819476513332, - "ci_upper": 0.23419150462246144, - "p_value": 0.0, - "is_significant": true, - "n_cluster": 347, - "n_baseline": 9623 - }, - "partial_delivery_rate": { - "metric": "partial_delivery_rate", - "cluster_value": 0.2564841498559078, - "baseline_value": 0.25875506598773773, - "difference": -0.0022709161318299476, - "effect_size": -0.0051927728948375496, - "effect_interpretation": "negligible", - "ci_lower": -0.04904385892944535, - "ci_upper": 0.044502026665785455, - "p_value": 0.9243898876848669, - "is_significant": false, - "n_cluster": 347, - "n_baseline": 9623 - }, - "return_rate": { - "metric": "return_rate", - "cluster_value": 0.044444444444444446, - "baseline_value": 0.0122, - "difference": 0.032244444444444444, - "effect_size": 0.2034655450753462, - "effect_interpretation": "small", - "ci_lower": 0.010848051862244128, - "ci_upper": 0.05364083702664476, - "p_value": 1.5800011210487241e-07, - "is_significant": true, - "n_cluster": 360, - "n_baseline": 10000 - } - }, - "summary": "Shows medium higher order to delivery days, small higher delivery delay days, small higher order to invoice days, small higher delay probability, small higher return rate", - "is_notable": true - }, - "2": { - "cluster_id": 2, - "n_documents": 141, - "effect_sizes": { - "order_to_delivery_days": { - "metric": "order_to_delivery_days", - "cluster_value": 20.434782608695652, - "baseline_value": 7.330770030136132, - "difference": 13.10401257855952, - "effect_size": 2.0888886805533273, - "effect_interpretation": "large", - "ci_lower": 12.557787146457347, - "ci_upper": 13.650238010661692, - "p_value": 2.4426054426922514e-127, - "is_significant": true, - "n_cluster": 138, - "n_baseline": 9623 - }, - "delivery_delay_days": { - "metric": "delivery_delay_days", - "cluster_value": 11.043478260869565, - "baseline_value": -2.192559492881638, - "difference": 13.236037753751202, - "effect_size": 1.922383542770125, - "effect_interpretation": "large", - "ci_lower": 12.570751005864865, - "ci_upper": 13.901324501637538, - "p_value": 1.2706070059496393e-108, - "is_significant": true, - "n_cluster": 138, - "n_baseline": 9623 - }, - "invoice_lag_days": { - "metric": "invoice_lag_days", - "cluster_value": 2.488721804511278, - "baseline_value": 2.9398682932095435, - "difference": -0.45114648869826546, - "effect_size": -0.14811612360224558, - "effect_interpretation": "negligible", - "ci_lower": -0.8405820651915608, - "ci_upper": -0.061710912204970214, - "p_value": 0.08991410502907055, - "is_significant": false, - "n_cluster": 133, - "n_baseline": 9263 - }, - "order_to_invoice_days": { - "metric": "order_to_invoice_days", - "cluster_value": 22.93233082706767, - "baseline_value": 10.27302169923351, - "difference": 12.65930912783416, - "effect_size": 1.818130200529613, - "effect_interpretation": "large", - "ci_lower": 12.023119983156626, - "ci_upper": 13.295498272511693, - "p_value": 3.825155380923517e-94, - "is_significant": true, - "n_cluster": 133, - "n_baseline": 9263 - }, - "delay_probability": { - "metric": "delay_probability", - "cluster_value": 0.8405797101449275, - "baseline_value": 0.10506079185285254, - "difference": 0.7355189182920749, - "effect_size": 1.6599558007893183, - "effect_interpretation": "large", - "ci_lower": 0.6741365284917854, - "ci_upper": 0.7969013080923645, - "p_value": 0.0, - "is_significant": true, - "n_cluster": 138, - "n_baseline": 9623 - }, - "partial_delivery_rate": { - "metric": "partial_delivery_rate", - "cluster_value": 0.21014492753623187, - "baseline_value": 0.25875506598773773, - "difference": -0.04861013845150586, - "effect_size": -0.11487778921348113, - "effect_interpretation": "negligible", - "ci_lower": -0.11714485191814064, - "ci_upper": 0.019924575015128926, - "p_value": 0.19505727046509747, - "is_significant": false, - "n_cluster": 138, - "n_baseline": 9623 - }, - "return_rate": { - "metric": "return_rate", - "cluster_value": 0.0, - "baseline_value": 0.0122, - "difference": -0.0122, - "effect_size": -0.22135888240354246, - "effect_interpretation": "small", - "ci_lower": -0.0143516048633891, - "ci_upper": -0.010048395136610901, - "p_value": 0.1869936052674952, - "is_significant": false, - "n_cluster": 141, - "n_baseline": 10000 - } - }, - "summary": "Shows large higher order to delivery days, large higher delivery delay days, large higher order to invoice days, large higher delay probability", - "is_notable": true - }, - "3": { - "cluster_id": 3, - "n_documents": 819, - "effect_sizes": { - "order_to_delivery_days": { - "metric": "order_to_delivery_days", - "cluster_value": 11.359039190897597, - "baseline_value": 7.330770030136132, - "difference": 4.028269160761465, - "effect_size": 0.6036870840361938, - "effect_interpretation": "medium", - "ci_lower": 3.311598941848343, - "ci_upper": 4.744939379674587, - "p_value": 3.7846049812464003e-59, - "is_significant": true, - "n_cluster": 791, - "n_baseline": 9623 - }, - "delivery_delay_days": { - "metric": "delivery_delay_days", - "cluster_value": 1.8697850821744626, - "baseline_value": -2.192559492881638, - "difference": 4.0623445750561, - "effect_size": 0.5608673105013818, - "effect_interpretation": "medium", - "ci_lower": 3.323523697889217, - "ci_upper": 4.801165452222984, - "p_value": 2.1843656403560797e-51, - "is_significant": true, - "n_cluster": 791, - "n_baseline": 9623 - }, - "invoice_lag_days": { - "metric": "invoice_lag_days", - "cluster_value": 2.772068511198946, - "baseline_value": 2.9398682932095435, - "difference": -0.16779978201059764, - "effect_size": -0.05533183221139476, - "effect_interpretation": "negligible", - "ci_lower": -0.3721644140014533, - "ci_upper": 0.036564849980257996, - "p_value": 0.14280788075631054, - "is_significant": false, - "n_cluster": 759, - "n_baseline": 9263 - }, - "order_to_invoice_days": { - "metric": "order_to_invoice_days", - "cluster_value": 14.057971014492754, - "baseline_value": 10.27302169923351, - "difference": 3.7849493152592437, - "effect_size": 0.517524590216113, - "effect_interpretation": "medium", - "ci_lower": 3.030074650287562, - "ci_upper": 4.539823980230926, - "p_value": 2.213061346182728e-42, - "is_significant": true, - "n_cluster": 759, - "n_baseline": 9263 - }, - "delay_probability": { - "metric": "delay_probability", - "cluster_value": 0.3198482932996207, - "baseline_value": 0.10506079185285254, - "difference": 0.21478750144676817, - "effect_size": 0.5420175827950191, - "effect_interpretation": "medium", - "ci_lower": 0.1817113221324492, - "ci_upper": 0.24786368076108714, - "p_value": 0.0, - "is_significant": true, - "n_cluster": 791, - "n_baseline": 9623 - }, - "partial_delivery_rate": { - "metric": "partial_delivery_rate", - "cluster_value": 0.2743362831858407, - "baseline_value": 0.25875506598773773, - "difference": 0.015581217198102959, - "effect_size": 0.03524279167752242, - "effect_interpretation": "negligible", - "ci_lower": -0.01672001930386196, - "ci_upper": 0.04788245370006788, - "p_value": 0.3368375902042815, - "is_significant": false, - "n_cluster": 791, - "n_baseline": 9623 - }, - "return_rate": { - "metric": "return_rate", - "cluster_value": 0.05982905982905983, - "baseline_value": 0.0122, - "difference": 0.04762905982905983, - "effect_size": 0.27285497532126896, - "effect_interpretation": "small", - "ci_lower": 0.031244197319990348, - "ci_upper": 0.0640139223381293, - "p_value": 0.0, - "is_significant": true, - "n_cluster": 819, - "n_baseline": 10000 - } - }, - "summary": "Shows medium higher order to delivery days, medium higher delivery delay days, medium higher order to invoice days, medium higher delay probability, small higher return rate", - "is_notable": true - }, - "4": { - "cluster_id": 4, - "n_documents": 402, - "effect_sizes": { - "order_to_delivery_days": { - "metric": "order_to_delivery_days", - "cluster_value": 7.87948717948718, - "baseline_value": 7.330770030136132, - "difference": 0.5487171493510479, - "effect_size": 0.08581903716873698, - "effect_interpretation": "negligible", - "ci_lower": -0.28186682562066045, - "ci_upper": 1.3793011243227562, - "p_value": 0.09665303257716161, - "is_significant": false, - "n_cluster": 390, - "n_baseline": 9623 - }, - "delivery_delay_days": { - "metric": "delivery_delay_days", - "cluster_value": -1.505128205128205, - "baseline_value": -2.192559492881638, - "difference": 0.6874312877534328, - "effect_size": 0.09824626977206537, - "effect_interpretation": "negligible", - "ci_lower": -0.18890963124864368, - "ci_upper": 1.5637722067555093, - "p_value": 0.05719353245163846, - "is_significant": false, - "n_cluster": 390, - "n_baseline": 9623 - }, - "invoice_lag_days": { - "metric": "invoice_lag_days", - "cluster_value": 2.8346666666666667, - "baseline_value": 2.9398682932095435, - "difference": -0.10520162654287679, - "effect_size": -0.034497654478710525, - "effect_interpretation": "negligible", - "ci_lower": -0.4047483747187515, - "ci_upper": 0.19434512163299794, - "p_value": 0.5125355557147038, - "is_significant": false, - "n_cluster": 375, - "n_baseline": 9263 - }, - "order_to_invoice_days": { - "metric": "order_to_invoice_days", - "cluster_value": 10.826666666666666, - "baseline_value": 10.27302169923351, - "difference": 0.553644967433156, - "effect_size": 0.07828014298458208, - "effect_interpretation": "negligible", - "ci_lower": -0.33892789408336255, - "ci_upper": 1.4462178289496745, - "p_value": 0.13728395718955136, - "is_significant": false, - "n_cluster": 375, - "n_baseline": 9263 - }, - "delay_probability": { - "metric": "delay_probability", - "cluster_value": 0.16666666666666666, - "baseline_value": 0.10506079185285254, - "difference": 0.06160587481381412, - "effect_size": 0.18088305897515777, - "effect_interpretation": "negligible", - "ci_lower": 0.024114883057013987, - "ci_upper": 0.09909686657061426, - "p_value": 0.00011756729356537932, - "is_significant": true, - "n_cluster": 390, - "n_baseline": 9623 - }, - "partial_delivery_rate": { - "metric": "partial_delivery_rate", - "cluster_value": 0.2205128205128205, - "baseline_value": 0.25875506598773773, - "difference": -0.038242245474917225, - "effect_size": -0.0896532281396637, - "effect_interpretation": "negligible", - "ci_lower": -0.08030926388271598, - "ci_upper": 0.003824772932881526, - "p_value": 0.09031879617387295, - "is_significant": false, - "n_cluster": 390, - "n_baseline": 9623 - }, - "return_rate": { - "metric": "return_rate", - "cluster_value": 0.029850746268656716, - "baseline_value": 0.0122, - "difference": 0.017650746268656717, - "effect_size": 0.12593114076083745, - "effect_interpretation": "negligible", - "ci_lower": 0.0008768299969344057, - "ci_upper": 0.03442466254037903, - "p_value": 0.002090371705268046, - "is_significant": true, - "n_cluster": 402, - "n_baseline": 10000 - } - }, - "summary": "Shows negligible higher delay probability, negligible higher return rate", - "is_notable": false - }, - "5": { - "cluster_id": 5, - "n_documents": 195, - "effect_sizes": { - "order_to_delivery_days": { - "metric": "order_to_delivery_days", - "cluster_value": 5.597765363128492, - "baseline_value": 7.330770030136132, - "difference": -1.7330046670076404, - "effect_size": -0.27684980279866533, - "effect_interpretation": "small", - "ci_lower": -2.1555768813466276, - "ci_upper": -1.310432452668653, - "p_value": 0.00024381744592285803, - "is_significant": true, - "n_cluster": 179, - "n_baseline": 9623 - }, - "delivery_delay_days": { - "metric": "delivery_delay_days", - "cluster_value": -3.798882681564246, - "baseline_value": -2.192559492881638, - "difference": -1.606323188682608, - "effect_size": -0.23362637582949414, - "effect_interpretation": "small", - "ci_lower": -2.196601876969307, - "ci_upper": -1.0160445003959084, - "p_value": 0.00196018217673482, - "is_significant": true, - "n_cluster": 179, - "n_baseline": 9623 - }, - "invoice_lag_days": { - "metric": "invoice_lag_days", - "cluster_value": 2.8068181818181817, - "baseline_value": 2.9398682932095435, - "difference": -0.1330501113913618, - "effect_size": -0.043597357733636585, - "effect_interpretation": "negligible", - "ci_lower": -0.5575560673431804, - "ci_upper": 0.2914558445604568, - "p_value": 0.5666809282683396, - "is_significant": false, - "n_cluster": 176, - "n_baseline": 9263 - }, - "order_to_invoice_days": { - "metric": "order_to_invoice_days", - "cluster_value": 8.409090909090908, - "baseline_value": 10.27302169923351, - "difference": -1.8639307901426019, - "effect_size": -0.2680332404392412, - "effect_interpretation": "small", - "ci_lower": -2.4611956230940297, - "ci_upper": -1.2666659571911743, - "p_value": 0.0004294283667243441, - "is_significant": true, - "n_cluster": 176, - "n_baseline": 9263 - }, - "delay_probability": { - "metric": "delay_probability", - "cluster_value": 0.0111731843575419, - "baseline_value": 0.10506079185285254, - "difference": -0.09388760749531064, - "effect_size": -0.4483833691325778, - "effect_interpretation": "small", - "ci_lower": -0.11045982446038001, - "ci_upper": -0.07731539053024127, - "p_value": 4.340143844383526e-05, - "is_significant": true, - "n_cluster": 179, - "n_baseline": 9623 - }, - "partial_delivery_rate": { - "metric": "partial_delivery_rate", - "cluster_value": 0.8044692737430168, - "baseline_value": 0.25875506598773773, - "difference": 0.545714207755279, - "effect_size": 1.1582168702535651, - "effect_interpretation": "large", - "ci_lower": 0.48695797017142306, - "ci_upper": 0.604470445339135, - "p_value": 0.0, - "is_significant": true, - "n_cluster": 179, - "n_baseline": 9623 - }, - "return_rate": { - "metric": "return_rate", - "cluster_value": 0.0, - "baseline_value": 0.0122, - "difference": -0.0122, - "effect_size": -0.22135888240354246, - "effect_interpretation": "small", - "ci_lower": -0.0143516048633891, - "ci_upper": -0.010048395136610901, - "p_value": 0.12073089318188268, - "is_significant": false, - "n_cluster": 195, - "n_baseline": 10000 - } - }, - "summary": "Shows small lower order to delivery days, small lower delivery delay days, small lower order to invoice days, small lower delay probability, large higher partial delivery rate", - "is_notable": true - }, - "6": { - "cluster_id": 6, - "n_documents": 361, - "effect_sizes": { - "order_to_delivery_days": { - "metric": "order_to_delivery_days", - "cluster_value": 9.040697674418604, - "baseline_value": 7.330770030136132, - "difference": 1.7099276442824722, - "effect_size": 0.2669946726262322, - "effect_interpretation": "small", - "ci_lower": 0.780037151616081, - "ci_upper": 2.6398181369488634, - "p_value": 1.1573793988199327e-06, - "is_significant": true, - "n_cluster": 344, - "n_baseline": 9623 - }, - "delivery_delay_days": { - "metric": "delivery_delay_days", - "cluster_value": -0.45348837209302323, - "baseline_value": -2.192559492881638, - "difference": 1.7390711207886147, - "effect_size": 0.24829526198723673, - "effect_interpretation": "small", - "ci_lower": 0.7692552239153893, - "ci_upper": 2.7088870176618403, - "p_value": 6.1088543933829285e-06, - "is_significant": true, - "n_cluster": 344, - "n_baseline": 9623 - }, - "invoice_lag_days": { - "metric": "invoice_lag_days", - "cluster_value": 2.912121212121212, - "baseline_value": 2.9398682932095435, - "difference": -0.02774708108833135, - "effect_size": -0.009077905376635715, - "effect_interpretation": "negligible", - "ci_lower": -0.3661582039409607, - "ci_upper": 0.310664041764298, - "p_value": 0.8712721865088895, - "is_significant": false, - "n_cluster": 330, - "n_baseline": 9263 - }, - "order_to_invoice_days": { - "metric": "order_to_invoice_days", - "cluster_value": 11.94848484848485, - "baseline_value": 10.27302169923351, - "difference": 1.675463149251339, - "effect_size": 0.23650659818638975, - "effect_interpretation": "small", - "ci_lower": 0.6758053046797271, - "ci_upper": 2.6751209938229508, - "p_value": 2.445819573364152e-05, - "is_significant": true, - "n_cluster": 330, - "n_baseline": 9263 - }, - "delay_probability": { - "metric": "delay_probability", - "cluster_value": 0.22093023255813954, - "baseline_value": 0.10506079185285254, - "difference": 0.115869440705287, - "effect_size": 0.3184688179627343, - "effect_interpretation": "small", - "ci_lower": 0.07160202886306011, - "ci_upper": 0.1601368525475139, - "p_value": 1.2501111257279263e-11, - "is_significant": true, - "n_cluster": 344, - "n_baseline": 9623 - }, - "partial_delivery_rate": { - "metric": "partial_delivery_rate", - "cluster_value": 0.29651162790697677, - "baseline_value": 0.25875506598773773, - "difference": 0.03775656191923904, - "effect_size": 0.08435326942679677, - "effect_interpretation": "negligible", - "ci_lower": -0.011293666132859967, - "ci_upper": 0.08680678997133805, - "p_value": 0.11674250920631457, - "is_significant": false, - "n_cluster": 344, - "n_baseline": 9623 - }, - "return_rate": { - "metric": "return_rate", - "cluster_value": 0.04709141274238227, - "baseline_value": 0.0122, - "difference": 0.03489141274238227, - "effect_size": 0.21613287753109756, - "effect_interpretation": "small", - "ci_lower": 0.012933753032072923, - "ci_upper": 0.05684907245269162, - "p_value": 1.5044200329938917e-08, - "is_significant": true, - "n_cluster": 361, - "n_baseline": 10000 - } - }, - "summary": "Shows small higher order to delivery days, small higher delivery delay days, small higher order to invoice days, small higher delay probability, small higher return rate", - "is_notable": false - }, - "7": { - "cluster_id": 7, - "n_documents": 288, - "effect_sizes": { - "order_to_delivery_days": { - "metric": "order_to_delivery_days", - "cluster_value": 10.551601423487545, - "baseline_value": 7.330770030136132, - "difference": 3.220831393351413, - "effect_size": 0.5013341777068233, - "effect_interpretation": "medium", - "ci_lower": 2.086047795825265, - "ci_upper": 4.355614990877561, - "p_value": 1.3473847306365564e-16, - "is_significant": true, - "n_cluster": 281, - "n_baseline": 9623 - }, - "delivery_delay_days": { - "metric": "delivery_delay_days", - "cluster_value": 0.8647686832740213, - "baseline_value": -2.192559492881638, - "difference": 3.057328176155659, - "effect_size": 0.43494385453066153, - "effect_interpretation": "small", - "ci_lower": 1.865257028939256, - "ci_upper": 4.249399323372062, - "p_value": 7.110913867841114e-13, - "is_significant": true, - "n_cluster": 281, - "n_baseline": 9623 - }, - "invoice_lag_days": { - "metric": "invoice_lag_days", - "cluster_value": 2.9306569343065694, - "baseline_value": 2.9398682932095435, - "difference": -0.009211358902974087, - "effect_size": -0.00300992332034636, - "effect_interpretation": "negligible", - "ci_lower": -0.39511311579509945, - "ci_upper": 0.37669039798915127, - "p_value": 0.9608389053702521, - "is_significant": false, - "n_cluster": 274, - "n_baseline": 9263 - }, - "order_to_invoice_days": { - "metric": "order_to_invoice_days", - "cluster_value": 13.587591240875913, - "baseline_value": 10.27302169923351, - "difference": 3.3145695416424026, - "effect_size": 0.4661113477574285, - "effect_interpretation": "small", - "ci_lower": 2.0964078180836694, - "ci_upper": 4.532731265201136, - "p_value": 3.1455473339866566e-14, - "is_significant": true, - "n_cluster": 274, - "n_baseline": 9263 - }, - "delay_probability": { - "metric": "delay_probability", - "cluster_value": 0.28113879003558717, - "baseline_value": 0.10506079185285254, - "difference": 0.17607799818273462, - "effect_size": 0.45754675751018237, - "effect_interpretation": "small", - "ci_lower": 0.12315944527613878, - "ci_upper": 0.22899655108933045, - "p_value": 0.0, - "is_significant": true, - "n_cluster": 281, - "n_baseline": 9623 - }, - "partial_delivery_rate": { - "metric": "partial_delivery_rate", - "cluster_value": 0.28113879003558717, - "baseline_value": 0.25875506598773773, - "difference": 0.02238372404784944, - "effect_size": 0.05043117098144312, - "effect_interpretation": "negligible", - "ci_lower": -0.03090235038763737, - "ci_upper": 0.07566979848333624, - "p_value": 0.39875464748553413, - "is_significant": false, - "n_cluster": 281, - "n_baseline": 9623 - }, - "return_rate": { - "metric": "return_rate", - "cluster_value": 0.03125, - "baseline_value": 0.0122, - "difference": 0.019049999999999997, - "effect_size": 0.13406231928668105, - "effect_interpretation": "negligible", - "ci_lower": -0.0011596160865812756, - "ci_upper": 0.03925961608658127, - "p_value": 0.004472645112020723, - "is_significant": true, - "n_cluster": 288, - "n_baseline": 10000 - } - }, - "summary": "Shows medium higher order to delivery days, small higher delivery delay days, small higher order to invoice days, small higher delay probability, negligible higher return rate", - "is_notable": true - } - } -} \ No newline at end of file diff --git a/pattern-engine/test_output/evidence_ledger.json b/pattern-engine/test_output/evidence_ledger.json deleted file mode 100644 index ca8d527..0000000 --- a/pattern-engine/test_output/evidence_ledger.json +++ /dev/null @@ -1,6555 +0,0 @@ -{ - "metadata": { - "generated_at": "2025-12-27T23:53:08.577792Z", - "seed": 42, - "n_cards": 8 - }, - "entries": [ - { - "card_id": "PAT-F22349FF", - "doc_keys": [ - "0000000016", - "0000000045", - "0000000080", - "0000000113", - "0000000134", - "0000000185", - "0000000210", - "0000000239", - "0000000242", - "0000000252", - "0000000280", - "0000000316", - "0000000318", - "0000000323", - "0000000394", - "0000000423", - "0000000430", - "0000000451", - "0000000466", - "0000000490", - "0000000510", - "0000000525", - "0000000539", - "0000000590", - "0000000605", - "0000000653", - "0000000683", - "0000000694", - "0000000863", - "0000000866", - "0000000870", - "0000000880", - "0000000895", - "0000000935", - "0000000968", - "0000000970", - "0000000977", - "0000001015", - "0000001016", - "0000001060", - "0000001073", - "0000001082", - "0000001115", - "0000001119", - "0000001173", - "0000001195", - "0000001217", - "0000001248", - "0000001291", - "0000001297", - "0000001362", - "0000001405", - "0000001452", - "0000001493", - "0000001497", - "0000001506", - "0000001531", - "0000001591", - "0000001592", - "0000001635", - "0000001694", - "0000001779", - "0000001869", - "0000001946", - "0000001977", - "0000001979", - "0000002062", - "0000002091", - "0000002095", - "0000002257", - "0000002304", - "0000002397", - "0000002435", - "0000002442", - "0000002511", - "0000002513", - "0000002520", - "0000002534", - "0000002613", - "0000002619", - "0000002653", - "0000002704", - "0000002789", - "0000002795", - "0000002809", - "0000002812", - "0000002829", - "0000002847", - "0000002885", - "0000002914", - "0000002948", - "0000002978", - "0000002981", - "0000002983", - "0000003022", - "0000003029", - "0000003071", - "0000003125", - "0000003138", - "0000003148", - "0000003149", - "0000003182", - "0000003224", - "0000003239", - "0000003243", - "0000003256", - "0000003261", - "0000003273", - "0000003277", - "0000003303", - "0000003313", - "0000003316", - "0000003385", - "0000003415", - "0000003420", - "0000003428", - "0000003475", - "0000003525", - "0000003537", - "0000003541", - "0000003549", - "0000003577", - "0000003679", - "0000003682", - "0000003719", - "0000003721", - "0000003743", - "0000003782", - "0000003812", - "0000003814", - "0000003837", - "0000003848", - "0000003852", - "0000003859", - "0000003863", - "0000003907", - "0000003933", - "0000003938", - "0000004011", - "0000004046", - "0000004071", - "0000004082", - "0000004124", - "0000004130", - "0000004207", - "0000004212", - "0000004260", - "0000004286", - "0000004371", - "0000004396", - "0000004401", - "0000004404", - "0000004409", - "0000004445", - "0000004484", - "0000004550", - "0000004566", - "0000004590", - "0000004600", - "0000004627", - "0000004636", - "0000004642", - "0000004673", - "0000004688", - "0000004712", - "0000004739", - "0000004775", - "0000004815", - "0000004821", - "0000004864", - "0000004870", - "0000004889", - "0000004908", - "0000004912", - "0000004932", - "0000004948", - "0000004951", - "0000004976", - "0000005000", - "0000005016", - "0000005045", - "0000005048", - "0000005118", - "0000005162", - "0000005170", - "0000005186", - "0000005195", - "0000005202", - "0000005235", - "0000005239", - "0000005270", - "0000005294", - "0000005328", - "0000005355", - "0000005356", - "0000005376", - "0000005399", - "0000005416", - "0000005420", - "0000005436", - "0000005479", - "0000005492", - "0000005496", - "0000005536", - "0000005554", - "0000005568", - "0000005573", - "0000005582", - "0000005616", - "0000005682", - "0000005699", - "0000005764", - "0000005822", - "0000005823", - "0000005871", - "0000005897", - "0000005967", - "0000005971", - "0000006013", - "0000006025", - "0000006029", - "0000006030", - "0000006043", - "0000006063", - "0000006109", - "0000006128", - "0000006153", - "0000006158", - "0000006164", - "0000006205", - "0000006208", - "0000006238", - "0000006247", - "0000006299", - "0000006303", - "0000006350", - "0000006364", - "0000006404", - "0000006415", - "0000006423", - "0000006448", - "0000006486", - "0000006510", - "0000006514", - "0000006563", - "0000006593", - "0000006604", - "0000006612", - "0000006659", - "0000006702", - "0000006716", - "0000006728", - "0000006775", - "0000007002", - "0000007003", - "0000007030", - "0000007040", - "0000007128", - "0000007208", - "0000007264", - "0000007285", - "0000007295", - "0000007297", - "0000007302", - "0000007312", - "0000007373", - "0000007478", - "0000007517", - "0000007528", - "0000007535", - "0000007584", - "0000007596", - "0000007659", - "0000007684", - "0000007783", - "0000007798", - "0000007811", - "0000007819", - "0000007850", - "0000007864", - "0000007901", - "0000007974", - "0000007981", - "0000007987", - "0000007988", - "0000008000", - "0000008034", - "0000008071", - "0000008077", - "0000008102", - "0000008139", - "0000008175", - "0000008226", - "0000008258", - "0000008275", - "0000008289", - "0000008297", - "0000008305", - "0000008307", - "0000008373", - "0000008382", - "0000008411", - "0000008502", - "0000008534", - "0000008554", - "0000008584", - "0000008589", - "0000008590", - "0000008602", - "0000008656", - "0000008732", - "0000008756", - "0000008798", - "0000008815", - "0000008946", - "0000008955", - "0000008979", - "0000008998", - "0000009015", - "0000009031", - "0000009039", - "0000009071", - "0000009073", - "0000009075", - "0000009093", - "0000009102", - "0000009108", - "0000009141", - "0000009265", - "0000009311", - "0000009323", - "0000009351", - "0000009391", - "0000009437", - "0000009466", - "0000009469", - "0000009471", - "0000009543", - "0000009618", - "0000009669", - "0000009689", - "0000009759", - "0000009773", - "0000009832", - "0000009849", - "0000009917", - "0000009950" - ], - "fields_used": [ - "consolidated_text", - "order_to_delivery_days", - "delivery_to_invoice_days", - "order_to_invoice_days", - "delay_from_requested_days" - ], - "sample_size": 347, - "total_population": 10000, - "full_evidence": { - "doc_keys": [ - "0000000016", - "0000000045", - "0000000080", - "0000000113", - "0000000134", - "0000000185", - "0000000210", - "0000000239", - "0000000242", - "0000000252", - "0000000280", - "0000000316", - "0000000318", - "0000000323", - "0000000394", - "0000000423", - "0000000430", - "0000000451", - "0000000466", - "0000000490", - "0000000510", - "0000000525", - "0000000539", - "0000000590", - "0000000605", - "0000000653", - "0000000683", - "0000000694", - "0000000863", - "0000000866", - "0000000870", - "0000000880", - "0000000895", - "0000000935", - "0000000968", - "0000000970", - "0000000977", - "0000001015", - "0000001016", - "0000001060", - "0000001073", - "0000001082", - "0000001115", - "0000001119", - "0000001173", - "0000001195", - "0000001217", - "0000001248", - "0000001291", - "0000001297", - "0000001362", - "0000001405", - "0000001452", - "0000001493", - "0000001497", - "0000001506", - "0000001531", - "0000001591", - "0000001592", - "0000001635", - "0000001694", - "0000001779", - "0000001869", - "0000001946", - "0000001977", - "0000001979", - "0000002062", - "0000002091", - "0000002095", - "0000002257", - "0000002304", - "0000002397", - "0000002435", - "0000002442", - "0000002511", - "0000002513", - "0000002520", - "0000002534", - "0000002613", - "0000002619", - "0000002653", - "0000002704", - "0000002789", - "0000002795", - "0000002809", - "0000002812", - "0000002829", - "0000002847", - "0000002885", - "0000002914", - "0000002948", - "0000002978", - "0000002981", - "0000002983", - "0000003022", - "0000003029", - "0000003071", - "0000003125", - "0000003138", - "0000003148", - "0000003149", - "0000003182", - "0000003224", - "0000003239", - "0000003243", - "0000003256", - "0000003261", - "0000003273", - "0000003277", - "0000003303", - "0000003313", - "0000003316", - "0000003385", - "0000003415", - "0000003420", - "0000003428", - "0000003475", - "0000003525", - "0000003537", - "0000003541", - "0000003549", - "0000003577", - "0000003679", - "0000003682", - "0000003719", - "0000003721", - "0000003743", - "0000003782", - "0000003812", - "0000003814", - "0000003837", - "0000003848", - "0000003852", - "0000003859", - "0000003863", - "0000003907", - "0000003933", - "0000003938", - "0000004011", - "0000004046", - "0000004071", - "0000004082", - "0000004124", - "0000004130", - "0000004207", - "0000004212", - "0000004260", - "0000004286", - "0000004371", - "0000004396", - "0000004401", - "0000004404", - "0000004409", - "0000004445", - "0000004484", - "0000004550", - "0000004566", - "0000004590", - "0000004600", - "0000004627", - "0000004636", - "0000004642", - "0000004673", - "0000004688", - "0000004712", - "0000004739", - "0000004775", - "0000004815", - "0000004821", - "0000004864", - "0000004870", - "0000004889", - "0000004908", - "0000004912", - "0000004932", - "0000004948", - "0000004951", - "0000004976", - "0000005000", - "0000005016", - "0000005045", - "0000005048", - "0000005118", - "0000005162", - "0000005170", - "0000005186", - "0000005195", - "0000005202", - "0000005235", - "0000005239", - "0000005270", - "0000005294", - "0000005328", - "0000005355", - "0000005356", - "0000005376", - "0000005399", - "0000005416", - "0000005420", - "0000005436", - "0000005479", - "0000005492", - "0000005496", - "0000005536", - "0000005554", - "0000005568", - "0000005573", - "0000005582", - "0000005616", - "0000005682", - "0000005699", - "0000005764", - "0000005822", - "0000005823", - "0000005871", - "0000005897", - "0000005967", - "0000005971", - "0000006013", - "0000006025", - "0000006029", - "0000006030", - "0000006043", - "0000006063", - "0000006109", - "0000006128", - "0000006153", - "0000006158", - "0000006164", - "0000006205", - "0000006208", - "0000006238", - "0000006247", - "0000006299", - "0000006303", - "0000006350", - "0000006364", - "0000006404", - "0000006415", - "0000006423", - "0000006448", - "0000006486", - "0000006510", - "0000006514", - "0000006563", - "0000006593", - "0000006604", - "0000006612", - "0000006659", - "0000006702", - "0000006716", - "0000006728", - "0000006775", - "0000007002", - "0000007003", - "0000007030", - "0000007040", - "0000007128", - "0000007208", - "0000007264", - "0000007285", - "0000007295", - "0000007297", - "0000007302", - "0000007312", - "0000007373", - "0000007478", - "0000007517", - "0000007528", - "0000007535", - "0000007584", - "0000007596", - "0000007659", - "0000007684", - "0000007783", - "0000007798", - "0000007811", - "0000007819", - "0000007850", - "0000007864", - "0000007901", - "0000007974", - "0000007981", - "0000007987", - "0000007988", - "0000008000", - "0000008034", - "0000008071", - "0000008077", - "0000008102", - "0000008139", - "0000008175", - "0000008226", - "0000008258", - "0000008275", - "0000008289", - "0000008297", - "0000008305", - "0000008307", - "0000008373", - "0000008382", - "0000008411", - "0000008502", - "0000008534", - "0000008554", - "0000008584", - "0000008589", - "0000008590", - "0000008602", - "0000008656", - "0000008732", - "0000008756", - "0000008798", - "0000008815", - "0000008946", - "0000008955", - "0000008979", - "0000008998", - "0000009015", - "0000009031", - "0000009039", - "0000009071", - "0000009073", - "0000009075", - "0000009093", - "0000009102", - "0000009108", - "0000009141", - "0000009265", - "0000009311", - "0000009323", - "0000009351", - "0000009391", - "0000009437", - "0000009466", - "0000009469", - "0000009471", - "0000009543", - "0000009618", - "0000009669", - "0000009689", - "0000009759", - "0000009773", - "0000009832", - "0000009849", - "0000009917", - "0000009950" - ], - "n_documents": 347, - "field_usage": [ - { - "field_name": "consolidated_text", - "source_type": "unified", - "usage_type": "text", - "n_non_null": 347, - "n_total": 347, - "coverage": 1.0 - }, - { - "field_name": "order_to_delivery_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 333, - "n_total": 347, - "coverage": 0.9596541786743515 - }, - { - "field_name": "delivery_to_invoice_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 0, - "n_total": 347, - "coverage": 0.0 - }, - { - "field_name": "order_to_invoice_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 323, - "n_total": 347, - "coverage": 0.930835734870317 - }, - { - "field_name": "delay_from_requested_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 0, - "n_total": 347, - "coverage": 0.0 - } - ], - "row_counts": { - "total_documents": 10000, - "cluster_documents": 347 - }, - "sampling_warnings": [], - "reproducibility": { - "random_seed": 42, - "clustering_algorithm": "kmeans", - "embedding_model": "tfidf", - "n_clusters": 8, - "min_cluster_size": 5, - "delay_threshold_days": 7, - "analysis_timestamp": "2025-12-27T23:53:08.524827Z", - "package_version": "0.1.0", - "parameters": {} - }, - "source_files": [ - "../synthetic-data/sample_output/orders.json", - "../synthetic-data/sample_output/deliveries.json", - "../synthetic-data/sample_output/invoices.json", - "../synthetic-data/sample_output/doc_flows.json", - "../synthetic-data/sample_output/customers.json", - "../synthetic-data/sample_output/materials.json" - ], - "has_warnings": false, - "validation_issues": [ - "Low coverage (0%) for field delivery_to_invoice_days", - "Low coverage (0%) for field delay_from_requested_days" - ] - } - }, - { - "card_id": "PAT-7CF3DCD1", - "doc_keys": [ - "0000000020", - "0000000022", - "0000000051", - "0000000075", - "0000000125", - "0000000152", - "0000000184", - "0000000194", - "0000000216", - "0000000234", - "0000000241", - "0000000267", - "0000000296", - "0000000358", - "0000000412", - "0000000413", - "0000000465", - "0000000483", - "0000000502", - "0000000540", - "0000000567", - "0000000598", - "0000000610", - "0000000638", - "0000000681", - "0000000700", - "0000000753", - "0000000812", - "0000000823", - "0000000860", - "0000000881", - "0000000883", - "0000000892", - "0000000896", - "0000000902", - "0000000906", - "0000000951", - "0000000955", - "0000000992", - "0000001021", - "0000001032", - "0000001034", - "0000001035", - "0000001056", - "0000001059", - "0000001072", - "0000001117", - "0000001170", - "0000001194", - "0000001200", - "0000001244", - "0000001254", - "0000001261", - "0000001347", - "0000001348", - "0000001419", - "0000001426", - "0000001456", - "0000001465", - "0000001488", - "0000001586", - "0000001610", - "0000001644", - "0000001651", - "0000001665", - "0000001670", - "0000001675", - "0000001678", - "0000001681", - "0000001720", - "0000001742", - "0000001752", - "0000001882", - "0000001903", - "0000001907", - "0000001909", - "0000001917", - "0000001918", - "0000001919", - "0000001926", - "0000001928", - "0000002010", - "0000002061", - "0000002103", - "0000002111", - "0000002117", - "0000002196", - "0000002247", - "0000002349", - "0000002412", - "0000002415", - "0000002500", - "0000002541", - "0000002587", - "0000002638", - "0000002662", - "0000002711", - "0000002755", - "0000002788", - "0000002804", - "0000002837", - "0000002840", - "0000002841", - "0000002846", - "0000002853", - "0000002901", - "0000002903", - "0000002919", - "0000002976", - "0000002986", - "0000003031", - "0000003056", - "0000003114", - "0000003145", - "0000003151", - "0000003153", - "0000003255", - "0000003263", - "0000003269", - "0000003272", - "0000003317", - "0000003321", - "0000003370", - "0000003395", - "0000003432", - "0000003457", - "0000003464", - "0000003482", - "0000003505", - "0000003519", - "0000003562", - "0000003574", - "0000003585", - "0000003587", - "0000003639", - "0000003680", - "0000003724", - "0000003748", - "0000003766", - "0000003839", - "0000003876", - "0000003893", - "0000003909", - "0000004053", - "0000004081", - "0000004104", - "0000004118", - "0000004122", - "0000004140", - "0000004165", - "0000004188", - "0000004242", - "0000004262", - "0000004288", - "0000004290", - "0000004307", - "0000004317", - "0000004345", - "0000004355", - "0000004360", - "0000004398", - "0000004413", - "0000004420", - "0000004434", - "0000004455", - "0000004488", - "0000004532", - "0000004541", - "0000004575", - "0000004616", - "0000004619", - "0000004635", - "0000004650", - "0000004676", - "0000004705", - "0000004711", - "0000004724", - "0000004730", - "0000004778", - "0000004832", - "0000004964", - "0000005002", - "0000005028", - "0000005040", - "0000005076", - "0000005081", - "0000005093", - "0000005109", - "0000005240", - "0000005246", - "0000005250", - "0000005338", - "0000005402", - "0000005407", - "0000005415", - "0000005452", - "0000005455", - "0000005457", - "0000005467", - "0000005484", - "0000005494", - "0000005512", - "0000005532", - "0000005549", - "0000005589", - "0000005632", - "0000005643", - "0000005651", - "0000005696", - "0000005719", - "0000005725", - "0000005800", - "0000005814", - "0000005827", - "0000005828", - "0000005848", - "0000005943", - "0000005964", - "0000005986", - "0000006106", - "0000006172", - "0000006209", - "0000006226", - "0000006279", - "0000006296", - "0000006425", - "0000006459", - "0000006463", - "0000006474", - "0000006487", - "0000006508", - "0000006521", - "0000006633", - "0000006680", - "0000006715", - "0000006761", - "0000006779", - "0000006826", - "0000006845", - "0000006884", - "0000006891", - "0000006898", - "0000006911", - "0000006912", - "0000006913", - "0000006935", - "0000006959", - "0000006965", - "0000006991", - "0000007005", - "0000007022", - "0000007046", - "0000007082", - "0000007099", - "0000007121", - "0000007155", - "0000007195", - "0000007197", - "0000007214", - "0000007250", - "0000007261", - "0000007283", - "0000007371", - "0000007402", - "0000007536", - "0000007575", - "0000007606", - "0000007609", - "0000007706", - "0000007734", - "0000007744", - "0000007827", - "0000007835", - "0000007843", - "0000007847", - "0000007870", - "0000007877", - "0000007894", - "0000007905", - "0000007911", - "0000007963", - "0000007973", - "0000008029", - "0000008103", - "0000008147", - "0000008153", - "0000008186", - "0000008223", - "0000008270", - "0000008272", - "0000008280", - "0000008321", - "0000008322", - "0000008327", - "0000008353", - "0000008402", - "0000008417", - "0000008424", - "0000008442", - "0000008479", - "0000008485", - "0000008494", - "0000008518", - "0000008524", - "0000008538", - "0000008550", - "0000008553", - "0000008560", - "0000008606", - "0000008609", - "0000008673", - "0000008681", - "0000008687", - "0000008718", - "0000008731", - "0000008750", - "0000008773", - "0000008799", - "0000008863", - "0000008872", - "0000008881", - "0000008886", - "0000008887", - "0000008888", - "0000008899", - "0000009016", - "0000009022", - "0000009072", - "0000009091", - "0000009130", - "0000009158", - "0000009220", - "0000009264", - "0000009320", - "0000009321", - "0000009338", - "0000009448", - "0000009481", - "0000009508", - "0000009531", - "0000009538", - "0000009542", - "0000009545", - "0000009563", - "0000009568", - "0000009571", - "0000009583", - "0000009706", - "0000009757", - "0000009789", - "0000009814", - "0000009815", - "0000009817", - "0000009834", - "0000009844", - "0000009887", - "0000009896", - "0000009912", - "0000009915", - "0000009977" - ], - "fields_used": [ - "consolidated_text", - "order_to_delivery_days", - "delivery_to_invoice_days", - "order_to_invoice_days", - "delay_from_requested_days" - ], - "sample_size": 360, - "total_population": 10000, - "full_evidence": { - "doc_keys": [ - "0000000020", - "0000000022", - "0000000051", - "0000000075", - "0000000125", - "0000000152", - "0000000184", - "0000000194", - "0000000216", - "0000000234", - "0000000241", - "0000000267", - "0000000296", - "0000000358", - "0000000412", - "0000000413", - "0000000465", - "0000000483", - "0000000502", - "0000000540", - "0000000567", - "0000000598", - "0000000610", - "0000000638", - "0000000681", - "0000000700", - "0000000753", - "0000000812", - "0000000823", - "0000000860", - "0000000881", - "0000000883", - "0000000892", - "0000000896", - "0000000902", - "0000000906", - "0000000951", - "0000000955", - "0000000992", - "0000001021", - "0000001032", - "0000001034", - "0000001035", - "0000001056", - "0000001059", - "0000001072", - "0000001117", - "0000001170", - "0000001194", - "0000001200", - "0000001244", - "0000001254", - "0000001261", - "0000001347", - "0000001348", - "0000001419", - "0000001426", - "0000001456", - "0000001465", - "0000001488", - "0000001586", - "0000001610", - "0000001644", - "0000001651", - "0000001665", - "0000001670", - "0000001675", - "0000001678", - "0000001681", - "0000001720", - "0000001742", - "0000001752", - "0000001882", - "0000001903", - "0000001907", - "0000001909", - "0000001917", - "0000001918", - "0000001919", - "0000001926", - "0000001928", - "0000002010", - "0000002061", - "0000002103", - "0000002111", - "0000002117", - "0000002196", - "0000002247", - "0000002349", - "0000002412", - "0000002415", - "0000002500", - "0000002541", - "0000002587", - "0000002638", - "0000002662", - "0000002711", - "0000002755", - "0000002788", - "0000002804", - "0000002837", - "0000002840", - "0000002841", - "0000002846", - "0000002853", - "0000002901", - "0000002903", - "0000002919", - "0000002976", - "0000002986", - "0000003031", - "0000003056", - "0000003114", - "0000003145", - "0000003151", - "0000003153", - "0000003255", - "0000003263", - "0000003269", - "0000003272", - "0000003317", - "0000003321", - "0000003370", - "0000003395", - "0000003432", - "0000003457", - "0000003464", - "0000003482", - "0000003505", - "0000003519", - "0000003562", - "0000003574", - "0000003585", - "0000003587", - "0000003639", - "0000003680", - "0000003724", - "0000003748", - "0000003766", - "0000003839", - "0000003876", - "0000003893", - "0000003909", - "0000004053", - "0000004081", - "0000004104", - "0000004118", - "0000004122", - "0000004140", - "0000004165", - "0000004188", - "0000004242", - "0000004262", - "0000004288", - "0000004290", - "0000004307", - "0000004317", - "0000004345", - "0000004355", - "0000004360", - "0000004398", - "0000004413", - "0000004420", - "0000004434", - "0000004455", - "0000004488", - "0000004532", - "0000004541", - "0000004575", - "0000004616", - "0000004619", - "0000004635", - "0000004650", - "0000004676", - "0000004705", - "0000004711", - "0000004724", - "0000004730", - "0000004778", - "0000004832", - "0000004964", - "0000005002", - "0000005028", - "0000005040", - "0000005076", - "0000005081", - "0000005093", - "0000005109", - "0000005240", - "0000005246", - "0000005250", - "0000005338", - "0000005402", - "0000005407", - "0000005415", - "0000005452", - "0000005455", - "0000005457", - "0000005467", - "0000005484", - "0000005494", - "0000005512", - "0000005532", - "0000005549", - "0000005589", - "0000005632", - "0000005643", - "0000005651", - "0000005696", - "0000005719", - "0000005725", - "0000005800", - "0000005814", - "0000005827", - "0000005828", - "0000005848", - "0000005943", - "0000005964", - "0000005986", - "0000006106", - "0000006172", - "0000006209", - "0000006226", - "0000006279", - "0000006296", - "0000006425", - "0000006459", - "0000006463", - "0000006474", - "0000006487", - "0000006508", - "0000006521", - "0000006633", - "0000006680", - "0000006715", - "0000006761", - "0000006779", - "0000006826", - "0000006845", - "0000006884", - "0000006891", - "0000006898", - "0000006911", - "0000006912", - "0000006913", - "0000006935", - "0000006959", - "0000006965", - "0000006991", - "0000007005", - "0000007022", - "0000007046", - "0000007082", - "0000007099", - "0000007121", - "0000007155", - "0000007195", - "0000007197", - "0000007214", - "0000007250", - "0000007261", - "0000007283", - "0000007371", - "0000007402", - "0000007536", - "0000007575", - "0000007606", - "0000007609", - "0000007706", - "0000007734", - "0000007744", - "0000007827", - "0000007835", - "0000007843", - "0000007847", - "0000007870", - "0000007877", - "0000007894", - "0000007905", - "0000007911", - "0000007963", - "0000007973", - "0000008029", - "0000008103", - "0000008147", - "0000008153", - "0000008186", - "0000008223", - "0000008270", - "0000008272", - "0000008280", - "0000008321", - "0000008322", - "0000008327", - "0000008353", - "0000008402", - "0000008417", - "0000008424", - "0000008442", - "0000008479", - "0000008485", - "0000008494", - "0000008518", - "0000008524", - "0000008538", - "0000008550", - "0000008553", - "0000008560", - "0000008606", - "0000008609", - "0000008673", - "0000008681", - "0000008687", - "0000008718", - "0000008731", - "0000008750", - "0000008773", - "0000008799", - "0000008863", - "0000008872", - "0000008881", - "0000008886", - "0000008887", - "0000008888", - "0000008899", - "0000009016", - "0000009022", - "0000009072", - "0000009091", - "0000009130", - "0000009158", - "0000009220", - "0000009264", - "0000009320", - "0000009321", - "0000009338", - "0000009448", - "0000009481", - "0000009508", - "0000009531", - "0000009538", - "0000009542", - "0000009545", - "0000009563", - "0000009568", - "0000009571", - "0000009583", - "0000009706", - "0000009757", - "0000009789", - "0000009814", - "0000009815", - "0000009817", - "0000009834", - "0000009844", - "0000009887", - "0000009896", - "0000009912", - "0000009915", - "0000009977" - ], - "n_documents": 360, - "field_usage": [ - { - "field_name": "consolidated_text", - "source_type": "unified", - "usage_type": "text", - "n_non_null": 360, - "n_total": 360, - "coverage": 1.0 - }, - { - "field_name": "order_to_delivery_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 347, - "n_total": 360, - "coverage": 0.9638888888888889 - }, - { - "field_name": "delivery_to_invoice_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 0, - "n_total": 360, - "coverage": 0.0 - }, - { - "field_name": "order_to_invoice_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 340, - "n_total": 360, - "coverage": 0.9444444444444444 - }, - { - "field_name": "delay_from_requested_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 0, - "n_total": 360, - "coverage": 0.0 - } - ], - "row_counts": { - "total_documents": 10000, - "cluster_documents": 360 - }, - "sampling_warnings": [], - "reproducibility": { - "random_seed": 42, - "clustering_algorithm": "kmeans", - "embedding_model": "tfidf", - "n_clusters": 8, - "min_cluster_size": 5, - "delay_threshold_days": 7, - "analysis_timestamp": "2025-12-27T23:53:08.530594Z", - "package_version": "0.1.0", - "parameters": {} - }, - "source_files": [ - "../synthetic-data/sample_output/orders.json", - "../synthetic-data/sample_output/deliveries.json", - "../synthetic-data/sample_output/invoices.json", - "../synthetic-data/sample_output/doc_flows.json", - "../synthetic-data/sample_output/customers.json", - "../synthetic-data/sample_output/materials.json" - ], - "has_warnings": false, - "validation_issues": [ - "Low coverage (0%) for field delivery_to_invoice_days", - "Low coverage (0%) for field delay_from_requested_days" - ] - } - }, - { - "card_id": "PAT-76CDCA00", - "doc_keys": [ - "0000000101", - "0000000281", - "0000000486", - "0000000604", - "0000000847", - "0000000927", - "0000000931", - "0000000952", - "0000001068", - "0000001125", - "0000001138", - "0000001165", - "0000001199", - "0000001230", - "0000001322", - "0000001378", - "0000001396", - "0000001443", - "0000001447", - "0000001462", - "0000001525", - "0000001597", - "0000001831", - "0000001856", - "0000001860", - "0000001930", - "0000001952", - "0000001956", - "0000001962", - "0000001966", - "0000001980", - "0000002063", - "0000002102", - "0000002421", - "0000002502", - "0000002524", - "0000002533", - "0000002629", - "0000002715", - "0000002726", - "0000002728", - "0000002793", - "0000002820", - "0000002848", - "0000002932", - "0000003003", - "0000003010", - "0000003052", - "0000003064", - "0000003123", - "0000003176", - "0000003225", - "0000003234", - "0000003250", - "0000003352", - "0000003449", - "0000003460", - "0000003649", - "0000003753", - "0000003770", - "0000003857", - "0000003905", - "0000003926", - "0000004229", - "0000004269", - "0000004342", - "0000004346", - "0000004397", - "0000004443", - "0000004464", - "0000004476", - "0000004527", - "0000004587", - "0000004647", - "0000004862", - "0000005106", - "0000005122", - "0000005184", - "0000005244", - "0000005269", - "0000005332", - "0000005350", - "0000005447", - "0000005518", - "0000005556", - "0000005562", - "0000005570", - "0000005619", - "0000005668", - "0000005908", - "0000005929", - "0000005956", - "0000005980", - "0000006140", - "0000006198", - "0000006473", - "0000006540", - "0000006576", - "0000006592", - "0000006630", - "0000006691", - "0000006722", - "0000006744", - "0000006852", - "0000006960", - "0000007165", - "0000007170", - "0000007202", - "0000007267", - "0000007347", - "0000007377", - "0000007482", - "0000007513", - "0000007522", - "0000007579", - "0000007687", - "0000007719", - "0000007902", - "0000008010", - "0000008044", - "0000008116", - "0000008125", - "0000008211", - "0000008419", - "0000008420", - "0000008434", - "0000008452", - "0000008688", - "0000008793", - "0000008934", - "0000009242", - "0000009245", - "0000009249", - "0000009283", - "0000009319", - "0000009334", - "0000009445", - "0000009524", - "0000009588", - "0000009593", - "0000009663" - ], - "fields_used": [ - "consolidated_text", - "order_to_delivery_days", - "delivery_to_invoice_days", - "order_to_invoice_days", - "delay_from_requested_days" - ], - "sample_size": 141, - "total_population": 10000, - "full_evidence": { - "doc_keys": [ - "0000000101", - "0000000281", - "0000000486", - "0000000604", - "0000000847", - "0000000927", - "0000000931", - "0000000952", - "0000001068", - "0000001125", - "0000001138", - "0000001165", - "0000001199", - "0000001230", - "0000001322", - "0000001378", - "0000001396", - "0000001443", - "0000001447", - "0000001462", - "0000001525", - "0000001597", - "0000001831", - "0000001856", - "0000001860", - "0000001930", - "0000001952", - "0000001956", - "0000001962", - "0000001966", - "0000001980", - "0000002063", - "0000002102", - "0000002421", - "0000002502", - "0000002524", - "0000002533", - "0000002629", - "0000002715", - "0000002726", - "0000002728", - "0000002793", - "0000002820", - "0000002848", - "0000002932", - "0000003003", - "0000003010", - "0000003052", - "0000003064", - "0000003123", - "0000003176", - "0000003225", - "0000003234", - "0000003250", - "0000003352", - "0000003449", - "0000003460", - "0000003649", - "0000003753", - "0000003770", - "0000003857", - "0000003905", - "0000003926", - "0000004229", - "0000004269", - "0000004342", - "0000004346", - "0000004397", - "0000004443", - "0000004464", - "0000004476", - "0000004527", - "0000004587", - "0000004647", - "0000004862", - "0000005106", - "0000005122", - "0000005184", - "0000005244", - "0000005269", - "0000005332", - "0000005350", - "0000005447", - "0000005518", - "0000005556", - "0000005562", - "0000005570", - "0000005619", - "0000005668", - "0000005908", - "0000005929", - "0000005956", - "0000005980", - "0000006140", - "0000006198", - "0000006473", - "0000006540", - "0000006576", - "0000006592", - "0000006630", - "0000006691", - "0000006722", - "0000006744", - "0000006852", - "0000006960", - "0000007165", - "0000007170", - "0000007202", - "0000007267", - "0000007347", - "0000007377", - "0000007482", - "0000007513", - "0000007522", - "0000007579", - "0000007687", - "0000007719", - "0000007902", - "0000008010", - "0000008044", - "0000008116", - "0000008125", - "0000008211", - "0000008419", - "0000008420", - "0000008434", - "0000008452", - "0000008688", - "0000008793", - "0000008934", - "0000009242", - "0000009245", - "0000009249", - "0000009283", - "0000009319", - "0000009334", - "0000009445", - "0000009524", - "0000009588", - "0000009593", - "0000009663" - ], - "n_documents": 141, - "field_usage": [ - { - "field_name": "consolidated_text", - "source_type": "unified", - "usage_type": "text", - "n_non_null": 141, - "n_total": 141, - "coverage": 1.0 - }, - { - "field_name": "order_to_delivery_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 138, - "n_total": 141, - "coverage": 0.9787234042553191 - }, - { - "field_name": "delivery_to_invoice_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 0, - "n_total": 141, - "coverage": 0.0 - }, - { - "field_name": "order_to_invoice_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 133, - "n_total": 141, - "coverage": 0.9432624113475178 - }, - { - "field_name": "delay_from_requested_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 0, - "n_total": 141, - "coverage": 0.0 - } - ], - "row_counts": { - "total_documents": 10000, - "cluster_documents": 141 - }, - "sampling_warnings": [], - "reproducibility": { - "random_seed": 42, - "clustering_algorithm": "kmeans", - "embedding_model": "tfidf", - "n_clusters": 8, - "min_cluster_size": 5, - "delay_threshold_days": 7, - "analysis_timestamp": "2025-12-27T23:53:08.534528Z", - "package_version": "0.1.0", - "parameters": {} - }, - "source_files": [ - "../synthetic-data/sample_output/orders.json", - "../synthetic-data/sample_output/deliveries.json", - "../synthetic-data/sample_output/invoices.json", - "../synthetic-data/sample_output/doc_flows.json", - "../synthetic-data/sample_output/customers.json", - "../synthetic-data/sample_output/materials.json" - ], - "has_warnings": false, - "validation_issues": [ - "Low coverage (0%) for field delivery_to_invoice_days", - "Low coverage (0%) for field delay_from_requested_days" - ] - } - }, - { - "card_id": "PAT-CF84D0A6", - "doc_keys": [ - "0000000023", - "0000000028", - "0000000055", - "0000000063", - "0000000070", - "0000000084", - "0000000091", - "0000000096", - "0000000105", - "0000000111", - "0000000121", - "0000000151", - "0000000187", - "0000000206", - "0000000231", - "0000000232", - "0000000237", - "0000000240", - "0000000248", - "0000000265", - "0000000271", - "0000000282", - "0000000322", - "0000000326", - "0000000384", - "0000000390", - "0000000399", - "0000000400", - "0000000408", - "0000000436", - "0000000438", - "0000000445", - "0000000453", - "0000000454", - "0000000461", - "0000000467", - "0000000481", - "0000000496", - "0000000526", - "0000000527", - "0000000529", - "0000000541", - "0000000553", - "0000000554", - "0000000559", - "0000000574", - "0000000576", - "0000000580", - "0000000617", - "0000000624", - "0000000651", - "0000000659", - "0000000670", - "0000000688", - "0000000696", - "0000000706", - "0000000723", - "0000000736", - "0000000737", - "0000000745", - "0000000757", - "0000000761", - "0000000792", - "0000000811", - "0000000859", - "0000000886", - "0000000887", - "0000000905", - "0000000917", - "0000000924", - "0000000954", - "0000000997", - "0000001017", - "0000001038", - "0000001041", - "0000001043", - "0000001046", - "0000001058", - "0000001062", - "0000001067", - "0000001074", - "0000001079", - "0000001087", - "0000001118", - "0000001133", - "0000001158", - "0000001159", - "0000001197", - "0000001220", - "0000001226", - "0000001236", - "0000001237", - "0000001247", - "0000001287", - "0000001302", - "0000001306", - "0000001319", - "0000001325", - "0000001335", - "0000001350", - "0000001379", - "0000001394", - "0000001407", - "0000001423", - "0000001432", - "0000001433", - "0000001440", - "0000001489", - "0000001491", - "0000001496", - "0000001502", - "0000001509", - "0000001512", - "0000001513", - "0000001518", - "0000001544", - "0000001566", - "0000001578", - "0000001588", - "0000001603", - "0000001624", - "0000001633", - "0000001636", - "0000001639", - "0000001643", - "0000001648", - "0000001657", - "0000001660", - "0000001686", - "0000001689", - "0000001706", - "0000001714", - "0000001736", - "0000001751", - "0000001767", - "0000001789", - "0000001801", - "0000001806", - "0000001837", - "0000001843", - "0000001854", - "0000001866", - "0000001867", - "0000001885", - "0000001887", - "0000001895", - "0000001904", - "0000001912", - "0000001921", - "0000001940", - "0000001941", - "0000001942", - "0000001964", - "0000001971", - "0000001976", - "0000001985", - "0000002018", - "0000002036", - "0000002037", - "0000002039", - "0000002048", - "0000002072", - "0000002079", - "0000002084", - "0000002130", - "0000002150", - "0000002154", - "0000002184", - "0000002191", - "0000002215", - "0000002236", - "0000002240", - "0000002249", - "0000002253", - "0000002256", - "0000002269", - "0000002277", - "0000002289", - "0000002299", - "0000002316", - "0000002320", - "0000002326", - "0000002327", - "0000002329", - "0000002330", - "0000002339", - "0000002340", - "0000002345", - "0000002362", - "0000002395", - "0000002403", - "0000002419", - "0000002428", - "0000002446", - "0000002447", - "0000002455", - "0000002458", - "0000002463", - "0000002497", - "0000002510", - "0000002512", - "0000002529", - "0000002538", - "0000002544", - "0000002557", - "0000002579", - "0000002593", - "0000002604", - "0000002624", - "0000002646", - "0000002660", - "0000002668", - "0000002671", - "0000002687", - "0000002701", - "0000002707", - "0000002719", - "0000002729", - "0000002744", - "0000002761", - "0000002768", - "0000002784", - "0000002785", - "0000002796", - "0000002834", - "0000002835", - "0000002836", - "0000002845", - "0000002868", - "0000002869", - "0000002877", - "0000002880", - "0000002899", - "0000002907", - "0000002912", - "0000002934", - "0000002937", - "0000002956", - "0000002971", - "0000002977", - "0000002987", - "0000002991", - "0000003014", - "0000003019", - "0000003026", - "0000003040", - "0000003044", - "0000003047", - "0000003081", - "0000003090", - "0000003092", - "0000003100", - "0000003105", - "0000003135", - "0000003143", - "0000003179", - "0000003186", - "0000003208", - "0000003217", - "0000003223", - "0000003226", - "0000003241", - "0000003285", - "0000003291", - "0000003293", - "0000003330", - "0000003368", - "0000003372", - "0000003405", - "0000003421", - "0000003436", - "0000003448", - "0000003473", - "0000003495", - "0000003516", - "0000003517", - "0000003551", - "0000003555", - "0000003558", - "0000003568", - "0000003576", - "0000003581", - "0000003594", - "0000003606", - "0000003615", - "0000003618", - "0000003622", - "0000003637", - "0000003670", - "0000003676", - "0000003702", - "0000003713", - "0000003718", - "0000003732", - "0000003763", - "0000003774", - "0000003784", - "0000003789", - "0000003795", - "0000003813", - "0000003815", - "0000003819", - "0000003826", - "0000003835", - "0000003877", - "0000003886", - "0000003888", - "0000003906", - "0000003929", - "0000003946", - "0000003971", - "0000003972", - "0000003977", - "0000003978", - "0000003980", - "0000004015", - "0000004024", - "0000004025", - "0000004031", - "0000004052", - "0000004054", - "0000004058", - "0000004062", - "0000004085", - "0000004108", - "0000004114", - "0000004117", - "0000004137", - "0000004148", - "0000004151", - "0000004155", - "0000004168", - "0000004173", - "0000004213", - "0000004228", - "0000004230", - "0000004232", - "0000004261", - "0000004278", - "0000004282", - "0000004289", - "0000004299", - "0000004319", - "0000004330", - "0000004331", - "0000004334", - "0000004341", - "0000004356", - "0000004359", - "0000004369", - "0000004411", - "0000004421", - "0000004422", - "0000004423", - "0000004461", - "0000004471", - "0000004520", - "0000004522", - "0000004530", - "0000004540", - "0000004545", - "0000004557", - "0000004603", - "0000004615", - "0000004637", - "0000004648", - "0000004652", - "0000004704", - "0000004706", - "0000004707", - "0000004726", - "0000004733", - "0000004746", - "0000004782", - "0000004783", - "0000004800", - "0000004805", - "0000004835", - "0000004851", - "0000004881", - "0000004899", - "0000004903", - "0000004926", - "0000004943", - "0000004958", - "0000004971", - "0000004973", - "0000004980", - "0000004981", - "0000004982", - "0000004990", - "0000005032", - "0000005037", - "0000005042", - "0000005044", - "0000005047", - "0000005049", - "0000005057", - "0000005067", - "0000005134", - "0000005147", - "0000005148", - "0000005155", - "0000005159", - "0000005160", - "0000005165", - "0000005178", - "0000005179", - "0000005206", - "0000005218", - "0000005236", - "0000005238", - "0000005249", - "0000005252", - "0000005257", - "0000005287", - "0000005292", - "0000005304", - "0000005305", - "0000005311", - "0000005335", - "0000005336", - "0000005340", - "0000005352", - "0000005353", - "0000005385", - "0000005390", - "0000005400", - "0000005408", - "0000005422", - "0000005477", - "0000005482", - "0000005483", - "0000005488", - "0000005500", - "0000005544", - "0000005545", - "0000005546", - "0000005566", - "0000005572", - "0000005574", - "0000005594", - "0000005609", - "0000005629", - "0000005639", - "0000005675", - "0000005683", - "0000005706", - "0000005742", - "0000005746", - "0000005749", - "0000005762", - "0000005769", - "0000005811", - "0000005835", - "0000005846", - "0000005853", - "0000005856", - "0000005860", - "0000005865", - "0000005913", - "0000005914", - "0000005934", - "0000005953", - "0000006004", - "0000006010", - "0000006011", - "0000006032", - "0000006047", - "0000006056", - "0000006059", - "0000006061", - "0000006084", - "0000006119", - "0000006133", - "0000006169", - "0000006176", - "0000006190", - "0000006207", - "0000006229", - "0000006237", - "0000006239", - "0000006283", - "0000006306", - "0000006316", - "0000006356", - "0000006371", - "0000006381", - "0000006385", - "0000006389", - "0000006401", - "0000006412", - "0000006413", - "0000006418", - "0000006426", - "0000006443", - "0000006453", - "0000006464", - "0000006475", - "0000006498", - "0000006535", - "0000006537", - "0000006538", - "0000006542", - "0000006557", - "0000006582", - "0000006595", - "0000006615", - "0000006616", - "0000006634", - "0000006638", - "0000006645", - "0000006684", - "0000006689", - "0000006693", - "0000006720", - "0000006721", - "0000006755", - "0000006757", - "0000006759", - "0000006760", - "0000006765", - "0000006767", - "0000006781", - "0000006790", - "0000006806", - "0000006810", - "0000006820", - "0000006823", - "0000006834", - "0000006878", - "0000006896", - "0000006900", - "0000006903", - "0000006915", - "0000006919", - "0000006934", - "0000006958", - "0000006966", - "0000006985", - "0000007023", - "0000007043", - "0000007051", - "0000007058", - "0000007071", - "0000007079", - "0000007083", - "0000007084", - "0000007102", - "0000007106", - "0000007118", - "0000007120", - "0000007138", - "0000007141", - "0000007152", - "0000007161", - "0000007162", - "0000007175", - "0000007177", - "0000007181", - "0000007183", - "0000007184", - "0000007186", - "0000007187", - "0000007199", - "0000007222", - "0000007228", - "0000007260", - "0000007272", - "0000007274", - "0000007288", - "0000007313", - "0000007333", - "0000007353", - "0000007360", - "0000007361", - "0000007362", - "0000007363", - "0000007372", - "0000007375", - "0000007383", - "0000007390", - "0000007400", - "0000007403", - "0000007405", - "0000007410", - "0000007421", - "0000007455", - "0000007462", - "0000007463", - "0000007466", - "0000007473", - "0000007480", - "0000007491", - "0000007504", - "0000007506", - "0000007507", - "0000007520", - "0000007533", - "0000007558", - "0000007577", - "0000007601", - "0000007619", - "0000007628", - "0000007641", - "0000007656", - "0000007661", - "0000007671", - "0000007730", - "0000007735", - "0000007743", - "0000007754", - "0000007760", - "0000007761", - "0000007766", - "0000007768", - "0000007779", - "0000007789", - "0000007790", - "0000007793", - "0000007804", - "0000007830", - "0000007838", - "0000007841", - "0000007849", - "0000007874", - "0000007880", - "0000007898", - "0000007904", - "0000007915", - "0000007917", - "0000007920", - "0000007939", - "0000007955", - "0000007958", - "0000007967", - "0000007993", - "0000007995", - "0000007996", - "0000007997", - "0000008004", - "0000008008", - "0000008025", - "0000008036", - "0000008048", - "0000008062", - "0000008069", - "0000008081", - "0000008094", - "0000008097", - "0000008109", - "0000008122", - "0000008124", - "0000008134", - "0000008135", - "0000008140", - "0000008181", - "0000008184", - "0000008191", - "0000008213", - "0000008219", - "0000008234", - "0000008241", - "0000008243", - "0000008247", - "0000008254", - "0000008269", - "0000008271", - "0000008273", - "0000008279", - "0000008281", - "0000008283", - "0000008284", - "0000008301", - "0000008312", - "0000008319", - "0000008328", - "0000008340", - "0000008374", - "0000008376", - "0000008387", - "0000008390", - "0000008413", - "0000008416", - "0000008425", - "0000008430", - "0000008435", - "0000008437", - "0000008490", - "0000008569", - "0000008572", - "0000008577", - "0000008601", - "0000008607", - "0000008649", - "0000008651", - "0000008652", - "0000008665", - "0000008691", - "0000008698", - "0000008700", - "0000008711", - "0000008715", - "0000008717", - "0000008738", - "0000008739", - "0000008744", - "0000008747", - "0000008764", - "0000008777", - "0000008791", - "0000008805", - "0000008810", - "0000008821", - "0000008825", - "0000008867", - "0000008874", - "0000008885", - "0000008900", - "0000008912", - "0000008931", - "0000008932", - "0000008940", - "0000008943", - "0000008957", - "0000008961", - "0000008963", - "0000008976", - "0000008983", - "0000008993", - "0000008999", - "0000009042", - "0000009080", - "0000009085", - "0000009098", - "0000009099", - "0000009119", - "0000009127", - "0000009137", - "0000009146", - "0000009164", - "0000009171", - "0000009182", - "0000009185", - "0000009192", - "0000009212", - "0000009251", - "0000009261", - "0000009278", - "0000009299", - "0000009304", - "0000009313", - "0000009315", - "0000009318", - "0000009325", - "0000009344", - "0000009349", - "0000009379", - "0000009387", - "0000009389", - "0000009393", - "0000009399", - "0000009401", - "0000009424", - "0000009432", - "0000009446", - "0000009462", - "0000009489", - "0000009490", - "0000009499", - "0000009509", - "0000009523", - "0000009532", - "0000009541", - "0000009544", - "0000009552", - "0000009557", - "0000009592", - "0000009594", - "0000009631", - "0000009632", - "0000009639", - "0000009643", - "0000009644", - "0000009650", - "0000009666", - "0000009677", - "0000009678", - "0000009680", - "0000009690", - "0000009697", - "0000009708", - "0000009726", - "0000009727", - "0000009735", - "0000009751", - "0000009755", - "0000009769", - "0000009777", - "0000009778", - "0000009795", - "0000009805", - "0000009808", - "0000009838", - "0000009842", - "0000009857", - "0000009858", - "0000009860", - "0000009873", - "0000009876", - "0000009880", - "0000009898", - "0000009903", - "0000009908", - "0000009923", - "0000009979", - "0000009980", - "0000009981", - "0000009991" - ], - "fields_used": [ - "consolidated_text", - "order_to_delivery_days", - "delivery_to_invoice_days", - "order_to_invoice_days", - "delay_from_requested_days" - ], - "sample_size": 819, - "total_population": 10000, - "full_evidence": { - "doc_keys": [ - "0000000023", - "0000000028", - "0000000055", - "0000000063", - "0000000070", - "0000000084", - "0000000091", - "0000000096", - "0000000105", - "0000000111", - "0000000121", - "0000000151", - "0000000187", - "0000000206", - "0000000231", - "0000000232", - "0000000237", - "0000000240", - "0000000248", - "0000000265", - "0000000271", - "0000000282", - "0000000322", - "0000000326", - "0000000384", - "0000000390", - "0000000399", - "0000000400", - "0000000408", - "0000000436", - "0000000438", - "0000000445", - "0000000453", - "0000000454", - "0000000461", - "0000000467", - "0000000481", - "0000000496", - "0000000526", - "0000000527", - "0000000529", - "0000000541", - "0000000553", - "0000000554", - "0000000559", - "0000000574", - "0000000576", - "0000000580", - "0000000617", - "0000000624", - "0000000651", - "0000000659", - "0000000670", - "0000000688", - "0000000696", - "0000000706", - "0000000723", - "0000000736", - "0000000737", - "0000000745", - "0000000757", - "0000000761", - "0000000792", - "0000000811", - "0000000859", - "0000000886", - "0000000887", - "0000000905", - "0000000917", - "0000000924", - "0000000954", - "0000000997", - "0000001017", - "0000001038", - "0000001041", - "0000001043", - "0000001046", - "0000001058", - "0000001062", - "0000001067", - "0000001074", - "0000001079", - "0000001087", - "0000001118", - "0000001133", - "0000001158", - "0000001159", - "0000001197", - "0000001220", - "0000001226", - "0000001236", - "0000001237", - "0000001247", - "0000001287", - "0000001302", - "0000001306", - "0000001319", - "0000001325", - "0000001335", - "0000001350", - "0000001379", - "0000001394", - "0000001407", - "0000001423", - "0000001432", - "0000001433", - "0000001440", - "0000001489", - "0000001491", - "0000001496", - "0000001502", - "0000001509", - "0000001512", - "0000001513", - "0000001518", - "0000001544", - "0000001566", - "0000001578", - "0000001588", - "0000001603", - "0000001624", - "0000001633", - "0000001636", - "0000001639", - "0000001643", - "0000001648", - "0000001657", - "0000001660", - "0000001686", - "0000001689", - "0000001706", - "0000001714", - "0000001736", - "0000001751", - "0000001767", - "0000001789", - "0000001801", - "0000001806", - "0000001837", - "0000001843", - "0000001854", - "0000001866", - "0000001867", - "0000001885", - "0000001887", - "0000001895", - "0000001904", - "0000001912", - "0000001921", - "0000001940", - "0000001941", - "0000001942", - "0000001964", - "0000001971", - "0000001976", - "0000001985", - "0000002018", - "0000002036", - "0000002037", - "0000002039", - "0000002048", - "0000002072", - "0000002079", - "0000002084", - "0000002130", - "0000002150", - "0000002154", - "0000002184", - "0000002191", - "0000002215", - "0000002236", - "0000002240", - "0000002249", - "0000002253", - "0000002256", - "0000002269", - "0000002277", - "0000002289", - "0000002299", - "0000002316", - "0000002320", - "0000002326", - "0000002327", - "0000002329", - "0000002330", - "0000002339", - "0000002340", - "0000002345", - "0000002362", - "0000002395", - "0000002403", - "0000002419", - "0000002428", - "0000002446", - "0000002447", - "0000002455", - "0000002458", - "0000002463", - "0000002497", - "0000002510", - "0000002512", - "0000002529", - "0000002538", - "0000002544", - "0000002557", - "0000002579", - "0000002593", - "0000002604", - "0000002624", - "0000002646", - "0000002660", - "0000002668", - "0000002671", - "0000002687", - "0000002701", - "0000002707", - "0000002719", - "0000002729", - "0000002744", - "0000002761", - "0000002768", - "0000002784", - "0000002785", - "0000002796", - "0000002834", - "0000002835", - "0000002836", - "0000002845", - "0000002868", - "0000002869", - "0000002877", - "0000002880", - "0000002899", - "0000002907", - "0000002912", - "0000002934", - "0000002937", - "0000002956", - "0000002971", - "0000002977", - "0000002987", - "0000002991", - "0000003014", - "0000003019", - "0000003026", - "0000003040", - "0000003044", - "0000003047", - "0000003081", - "0000003090", - "0000003092", - "0000003100", - "0000003105", - "0000003135", - "0000003143", - "0000003179", - "0000003186", - "0000003208", - "0000003217", - "0000003223", - "0000003226", - "0000003241", - "0000003285", - "0000003291", - "0000003293", - "0000003330", - "0000003368", - "0000003372", - "0000003405", - "0000003421", - "0000003436", - "0000003448", - "0000003473", - "0000003495", - "0000003516", - "0000003517", - "0000003551", - "0000003555", - "0000003558", - "0000003568", - "0000003576", - "0000003581", - "0000003594", - "0000003606", - "0000003615", - "0000003618", - "0000003622", - "0000003637", - "0000003670", - "0000003676", - "0000003702", - "0000003713", - "0000003718", - "0000003732", - "0000003763", - "0000003774", - "0000003784", - "0000003789", - "0000003795", - "0000003813", - "0000003815", - "0000003819", - "0000003826", - "0000003835", - "0000003877", - "0000003886", - "0000003888", - "0000003906", - "0000003929", - "0000003946", - "0000003971", - "0000003972", - "0000003977", - "0000003978", - "0000003980", - "0000004015", - "0000004024", - "0000004025", - "0000004031", - "0000004052", - "0000004054", - "0000004058", - "0000004062", - "0000004085", - "0000004108", - "0000004114", - "0000004117", - "0000004137", - "0000004148", - "0000004151", - "0000004155", - "0000004168", - "0000004173", - "0000004213", - "0000004228", - "0000004230", - "0000004232", - "0000004261", - "0000004278", - "0000004282", - "0000004289", - "0000004299", - "0000004319", - "0000004330", - "0000004331", - "0000004334", - "0000004341", - "0000004356", - "0000004359", - "0000004369", - "0000004411", - "0000004421", - "0000004422", - "0000004423", - "0000004461", - "0000004471", - "0000004520", - "0000004522", - "0000004530", - "0000004540", - "0000004545", - "0000004557", - "0000004603", - "0000004615", - "0000004637", - "0000004648", - "0000004652", - "0000004704", - "0000004706", - "0000004707", - "0000004726", - "0000004733", - "0000004746", - "0000004782", - "0000004783", - "0000004800", - "0000004805", - "0000004835", - "0000004851", - "0000004881", - "0000004899", - "0000004903", - "0000004926", - "0000004943", - "0000004958", - "0000004971", - "0000004973", - "0000004980", - "0000004981", - "0000004982", - "0000004990", - "0000005032", - "0000005037", - "0000005042", - "0000005044", - "0000005047", - "0000005049", - "0000005057", - "0000005067", - "0000005134", - "0000005147", - "0000005148", - "0000005155", - "0000005159", - "0000005160", - "0000005165", - "0000005178", - "0000005179", - "0000005206", - "0000005218", - "0000005236", - "0000005238", - "0000005249", - "0000005252", - "0000005257", - "0000005287", - "0000005292", - "0000005304", - "0000005305", - "0000005311", - "0000005335", - "0000005336", - "0000005340", - "0000005352", - "0000005353", - "0000005385", - "0000005390", - "0000005400", - "0000005408", - "0000005422", - "0000005477", - "0000005482", - "0000005483", - "0000005488", - "0000005500", - "0000005544", - "0000005545", - "0000005546", - "0000005566", - "0000005572", - "0000005574", - "0000005594", - "0000005609", - "0000005629", - "0000005639", - "0000005675", - "0000005683", - "0000005706", - "0000005742", - "0000005746", - "0000005749", - "0000005762", - "0000005769", - "0000005811", - "0000005835", - "0000005846", - "0000005853", - "0000005856", - "0000005860", - "0000005865", - "0000005913", - "0000005914", - "0000005934", - "0000005953", - "0000006004", - "0000006010", - "0000006011", - "0000006032", - "0000006047", - "0000006056", - "0000006059", - "0000006061", - "0000006084", - "0000006119", - "0000006133", - "0000006169", - "0000006176", - "0000006190", - "0000006207", - "0000006229", - "0000006237", - "0000006239", - "0000006283", - "0000006306", - "0000006316", - "0000006356", - "0000006371", - "0000006381", - "0000006385", - "0000006389", - "0000006401", - "0000006412", - "0000006413", - "0000006418", - "0000006426", - "0000006443", - "0000006453", - "0000006464", - "0000006475", - "0000006498", - "0000006535", - "0000006537", - "0000006538", - "0000006542", - "0000006557", - "0000006582", - "0000006595", - "0000006615", - "0000006616", - "0000006634", - "0000006638", - "0000006645", - "0000006684", - "0000006689", - "0000006693", - "0000006720", - "0000006721", - "0000006755", - "0000006757", - "0000006759", - "0000006760", - "0000006765", - "0000006767", - "0000006781", - "0000006790", - "0000006806", - "0000006810", - "0000006820", - "0000006823", - "0000006834", - "0000006878", - "0000006896", - "0000006900", - "0000006903", - "0000006915", - "0000006919", - "0000006934", - "0000006958", - "0000006966", - "0000006985", - "0000007023", - "0000007043", - "0000007051", - "0000007058", - "0000007071", - "0000007079", - "0000007083", - "0000007084", - "0000007102", - "0000007106", - "0000007118", - "0000007120", - "0000007138", - "0000007141", - "0000007152", - "0000007161", - "0000007162", - "0000007175", - "0000007177", - "0000007181", - "0000007183", - "0000007184", - "0000007186", - "0000007187", - "0000007199", - "0000007222", - "0000007228", - "0000007260", - "0000007272", - "0000007274", - "0000007288", - "0000007313", - "0000007333", - "0000007353", - "0000007360", - "0000007361", - "0000007362", - "0000007363", - "0000007372", - "0000007375", - "0000007383", - "0000007390", - "0000007400", - "0000007403", - "0000007405", - "0000007410", - "0000007421", - "0000007455", - "0000007462", - "0000007463", - "0000007466", - "0000007473", - "0000007480", - "0000007491", - "0000007504", - "0000007506", - "0000007507", - "0000007520", - "0000007533", - "0000007558", - "0000007577", - "0000007601", - "0000007619", - "0000007628", - "0000007641", - "0000007656", - "0000007661", - "0000007671", - "0000007730", - "0000007735", - "0000007743", - "0000007754", - "0000007760", - "0000007761", - "0000007766", - "0000007768", - "0000007779", - "0000007789", - "0000007790", - "0000007793", - "0000007804", - "0000007830", - "0000007838", - "0000007841", - "0000007849", - "0000007874", - "0000007880", - "0000007898", - "0000007904", - "0000007915", - "0000007917", - "0000007920", - "0000007939", - "0000007955", - "0000007958", - "0000007967", - "0000007993", - "0000007995", - "0000007996", - "0000007997", - "0000008004", - "0000008008", - "0000008025", - "0000008036", - "0000008048", - "0000008062", - "0000008069", - "0000008081", - "0000008094", - "0000008097", - "0000008109", - "0000008122", - "0000008124", - "0000008134", - "0000008135", - "0000008140", - "0000008181", - "0000008184", - "0000008191", - "0000008213", - "0000008219", - "0000008234", - "0000008241", - "0000008243", - "0000008247", - "0000008254", - "0000008269", - "0000008271", - "0000008273", - "0000008279", - "0000008281", - "0000008283", - "0000008284", - "0000008301", - "0000008312", - "0000008319", - "0000008328", - "0000008340", - "0000008374", - "0000008376", - "0000008387", - "0000008390", - "0000008413", - "0000008416", - "0000008425", - "0000008430", - "0000008435", - "0000008437", - "0000008490", - "0000008569", - "0000008572", - "0000008577", - "0000008601", - "0000008607", - "0000008649", - "0000008651", - "0000008652", - "0000008665", - "0000008691", - "0000008698", - "0000008700", - "0000008711", - "0000008715", - "0000008717", - "0000008738", - "0000008739", - "0000008744", - "0000008747", - "0000008764", - "0000008777", - "0000008791", - "0000008805", - "0000008810", - "0000008821", - "0000008825", - "0000008867", - "0000008874", - "0000008885", - "0000008900", - "0000008912", - "0000008931", - "0000008932", - "0000008940", - "0000008943", - "0000008957", - "0000008961", - "0000008963", - "0000008976", - "0000008983", - "0000008993", - "0000008999", - "0000009042", - "0000009080", - "0000009085", - "0000009098", - "0000009099", - "0000009119", - "0000009127", - "0000009137", - "0000009146", - "0000009164", - "0000009171", - "0000009182", - "0000009185", - "0000009192", - "0000009212", - "0000009251", - "0000009261", - "0000009278", - "0000009299", - "0000009304", - "0000009313", - "0000009315", - "0000009318", - "0000009325", - "0000009344", - "0000009349", - "0000009379", - "0000009387", - "0000009389", - "0000009393", - "0000009399", - "0000009401", - "0000009424", - "0000009432", - "0000009446", - "0000009462", - "0000009489", - "0000009490", - "0000009499", - "0000009509", - "0000009523", - "0000009532", - "0000009541", - "0000009544", - "0000009552", - "0000009557", - "0000009592", - "0000009594", - "0000009631", - "0000009632", - "0000009639", - "0000009643", - "0000009644", - "0000009650", - "0000009666", - "0000009677", - "0000009678", - "0000009680", - "0000009690", - "0000009697", - "0000009708", - "0000009726", - "0000009727", - "0000009735", - "0000009751", - "0000009755", - "0000009769", - "0000009777", - "0000009778", - "0000009795", - "0000009805", - "0000009808", - "0000009838", - "0000009842", - "0000009857", - "0000009858", - "0000009860", - "0000009873", - "0000009876", - "0000009880", - "0000009898", - "0000009903", - "0000009908", - "0000009923", - "0000009979", - "0000009980", - "0000009981", - "0000009991" - ], - "n_documents": 819, - "field_usage": [ - { - "field_name": "consolidated_text", - "source_type": "unified", - "usage_type": "text", - "n_non_null": 819, - "n_total": 819, - "coverage": 1.0 - }, - { - "field_name": "order_to_delivery_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 791, - "n_total": 819, - "coverage": 0.9658119658119658 - }, - { - "field_name": "delivery_to_invoice_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 0, - "n_total": 819, - "coverage": 0.0 - }, - { - "field_name": "order_to_invoice_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 759, - "n_total": 819, - "coverage": 0.9267399267399268 - }, - { - "field_name": "delay_from_requested_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 0, - "n_total": 819, - "coverage": 0.0 - } - ], - "row_counts": { - "total_documents": 10000, - "cluster_documents": 819 - }, - "sampling_warnings": [], - "reproducibility": { - "random_seed": 42, - "clustering_algorithm": "kmeans", - "embedding_model": "tfidf", - "n_clusters": 8, - "min_cluster_size": 5, - "delay_threshold_days": 7, - "analysis_timestamp": "2025-12-27T23:53:08.547803Z", - "package_version": "0.1.0", - "parameters": {} - }, - "source_files": [ - "../synthetic-data/sample_output/orders.json", - "../synthetic-data/sample_output/deliveries.json", - "../synthetic-data/sample_output/invoices.json", - "../synthetic-data/sample_output/doc_flows.json", - "../synthetic-data/sample_output/customers.json", - "../synthetic-data/sample_output/materials.json" - ], - "has_warnings": false, - "validation_issues": [ - "Low coverage (0%) for field delivery_to_invoice_days", - "Low coverage (0%) for field delay_from_requested_days" - ] - } - }, - { - "card_id": "PAT-43D46B4A", - "doc_keys": [ - "0000000007", - "0000000019", - "0000000031", - "0000000041", - "0000000078", - "0000000099", - "0000000124", - "0000000138", - "0000000139", - "0000000183", - "0000000186", - "0000000254", - "0000000262", - "0000000284", - "0000000313", - "0000000352", - "0000000363", - "0000000368", - "0000000420", - "0000000446", - "0000000491", - "0000000545", - "0000000552", - "0000000568", - "0000000591", - "0000000632", - "0000000698", - "0000000715", - "0000000731", - "0000000744", - "0000000771", - "0000000776", - "0000000851", - "0000000930", - "0000000964", - "0000000967", - "0000000969", - "0000000994", - "0000001022", - "0000001027", - "0000001116", - "0000001224", - "0000001298", - "0000001304", - "0000001309", - "0000001352", - "0000001374", - "0000001376", - "0000001382", - "0000001422", - "0000001500", - "0000001607", - "0000001684", - "0000001707", - "0000001725", - "0000001726", - "0000001732", - "0000001739", - "0000001744", - "0000001797", - "0000001803", - "0000001805", - "0000001820", - "0000001861", - "0000001873", - "0000001929", - "0000001954", - "0000001994", - "0000001995", - "0000002007", - "0000002011", - "0000002024", - "0000002044", - "0000002077", - "0000002083", - "0000002099", - "0000002137", - "0000002138", - "0000002140", - "0000002147", - "0000002186", - "0000002206", - "0000002238", - "0000002263", - "0000002273", - "0000002334", - "0000002378", - "0000002386", - "0000002398", - "0000002407", - "0000002420", - "0000002429", - "0000002432", - "0000002437", - "0000002475", - "0000002537", - "0000002561", - "0000002569", - "0000002594", - "0000002610", - "0000002611", - "0000002627", - "0000002633", - "0000002634", - "0000002706", - "0000002717", - "0000002732", - "0000002734", - "0000002791", - "0000002855", - "0000002916", - "0000002917", - "0000002920", - "0000002921", - "0000002941", - "0000002969", - "0000003004", - "0000003009", - "0000003033", - "0000003036", - "0000003045", - "0000003053", - "0000003104", - "0000003110", - "0000003112", - "0000003121", - "0000003139", - "0000003174", - "0000003289", - "0000003314", - "0000003345", - "0000003360", - "0000003371", - "0000003381", - "0000003459", - "0000003509", - "0000003510", - "0000003564", - "0000003590", - "0000003591", - "0000003642", - "0000003664", - "0000003666", - "0000003712", - "0000003739", - "0000003777", - "0000003798", - "0000003807", - "0000003821", - "0000003831", - "0000003845", - "0000003847", - "0000003873", - "0000003913", - "0000003917", - "0000003925", - "0000003935", - "0000003955", - "0000004020", - "0000004050", - "0000004080", - "0000004088", - "0000004115", - "0000004136", - "0000004180", - "0000004186", - "0000004218", - "0000004253", - "0000004349", - "0000004419", - "0000004429", - "0000004442", - "0000004472", - "0000004533", - "0000004543", - "0000004629", - "0000004664", - "0000004684", - "0000004686", - "0000004697", - "0000004719", - "0000004720", - "0000004784", - "0000004785", - "0000004824", - "0000004833", - "0000004861", - "0000004930", - "0000004978", - "0000005025", - "0000005029", - "0000005039", - "0000005055", - "0000005060", - "0000005089", - "0000005091", - "0000005126", - "0000005137", - "0000005142", - "0000005200", - "0000005220", - "0000005222", - "0000005274", - "0000005283", - "0000005288", - "0000005342", - "0000005359", - "0000005360", - "0000005393", - "0000005446", - "0000005465", - "0000005469", - "0000005508", - "0000005586", - "0000005596", - "0000005613", - "0000005624", - "0000005630", - "0000005649", - "0000005654", - "0000005692", - "0000005723", - "0000005728", - "0000005759", - "0000005766", - "0000005775", - "0000005779", - "0000005808", - "0000005809", - "0000005810", - "0000005831", - "0000005842", - "0000005857", - "0000005954", - "0000005960", - "0000005969", - "0000005992", - "0000006038", - "0000006041", - "0000006077", - "0000006089", - "0000006101", - "0000006122", - "0000006151", - "0000006152", - "0000006183", - "0000006187", - "0000006213", - "0000006251", - "0000006255", - "0000006286", - "0000006352", - "0000006360", - "0000006376", - "0000006386", - "0000006429", - "0000006431", - "0000006451", - "0000006452", - "0000006494", - "0000006502", - "0000006527", - "0000006591", - "0000006613", - "0000006622", - "0000006624", - "0000006640", - "0000006675", - "0000006735", - "0000006747", - "0000006799", - "0000006838", - "0000006866", - "0000006868", - "0000006881", - "0000006918", - "0000006994", - "0000006996", - "0000007047", - "0000007052", - "0000007055", - "0000007077", - "0000007092", - "0000007097", - "0000007126", - "0000007192", - "0000007196", - "0000007220", - "0000007223", - "0000007268", - "0000007293", - "0000007315", - "0000007317", - "0000007321", - "0000007331", - "0000007355", - "0000007369", - "0000007392", - "0000007412", - "0000007427", - "0000007454", - "0000007485", - "0000007509", - "0000007512", - "0000007527", - "0000007552", - "0000007557", - "0000007566", - "0000007573", - "0000007576", - "0000007581", - "0000007598", - "0000007607", - "0000007646", - "0000007652", - "0000007683", - "0000007691", - "0000007693", - "0000007698", - "0000007712", - "0000007753", - "0000007797", - "0000007807", - "0000007820", - "0000007857", - "0000007879", - "0000007890", - "0000007937", - "0000007971", - "0000008001", - "0000008002", - "0000008130", - "0000008151", - "0000008174", - "0000008188", - "0000008195", - "0000008264", - "0000008303", - "0000008377", - "0000008441", - "0000008516", - "0000008522", - "0000008540", - "0000008541", - "0000008579", - "0000008592", - "0000008655", - "0000008703", - "0000008707", - "0000008716", - "0000008746", - "0000008826", - "0000008846", - "0000008896", - "0000008902", - "0000008907", - "0000008929", - "0000008933", - "0000008952", - "0000009037", - "0000009065", - "0000009067", - "0000009077", - "0000009092", - "0000009135", - "0000009154", - "0000009169", - "0000009225", - "0000009226", - "0000009237", - "0000009254", - "0000009277", - "0000009330", - "0000009332", - "0000009337", - "0000009352", - "0000009360", - "0000009378", - "0000009381", - "0000009390", - "0000009422", - "0000009427", - "0000009428", - "0000009498", - "0000009512", - "0000009534", - "0000009599", - "0000009607", - "0000009642", - "0000009719", - "0000009728", - "0000009774", - "0000009788", - "0000009790", - "0000009793", - "0000009807", - "0000009848", - "0000009853", - "0000009855", - "0000009867", - "0000009929", - "0000009995" - ], - "fields_used": [ - "consolidated_text", - "order_to_delivery_days", - "delivery_to_invoice_days", - "order_to_invoice_days", - "delay_from_requested_days" - ], - "sample_size": 402, - "total_population": 10000, - "full_evidence": { - "doc_keys": [ - "0000000007", - "0000000019", - "0000000031", - "0000000041", - "0000000078", - "0000000099", - "0000000124", - "0000000138", - "0000000139", - "0000000183", - "0000000186", - "0000000254", - "0000000262", - "0000000284", - "0000000313", - "0000000352", - "0000000363", - "0000000368", - "0000000420", - "0000000446", - "0000000491", - "0000000545", - "0000000552", - "0000000568", - "0000000591", - "0000000632", - "0000000698", - "0000000715", - "0000000731", - "0000000744", - "0000000771", - "0000000776", - "0000000851", - "0000000930", - "0000000964", - "0000000967", - "0000000969", - "0000000994", - "0000001022", - "0000001027", - "0000001116", - "0000001224", - "0000001298", - "0000001304", - "0000001309", - "0000001352", - "0000001374", - "0000001376", - "0000001382", - "0000001422", - "0000001500", - "0000001607", - "0000001684", - "0000001707", - "0000001725", - "0000001726", - "0000001732", - "0000001739", - "0000001744", - "0000001797", - "0000001803", - "0000001805", - "0000001820", - "0000001861", - "0000001873", - "0000001929", - "0000001954", - "0000001994", - "0000001995", - "0000002007", - "0000002011", - "0000002024", - "0000002044", - "0000002077", - "0000002083", - "0000002099", - "0000002137", - "0000002138", - "0000002140", - "0000002147", - "0000002186", - "0000002206", - "0000002238", - "0000002263", - "0000002273", - "0000002334", - "0000002378", - "0000002386", - "0000002398", - "0000002407", - "0000002420", - "0000002429", - "0000002432", - "0000002437", - "0000002475", - "0000002537", - "0000002561", - "0000002569", - "0000002594", - "0000002610", - "0000002611", - "0000002627", - "0000002633", - "0000002634", - "0000002706", - "0000002717", - "0000002732", - "0000002734", - "0000002791", - "0000002855", - "0000002916", - "0000002917", - "0000002920", - "0000002921", - "0000002941", - "0000002969", - "0000003004", - "0000003009", - "0000003033", - "0000003036", - "0000003045", - "0000003053", - "0000003104", - "0000003110", - "0000003112", - "0000003121", - "0000003139", - "0000003174", - "0000003289", - "0000003314", - "0000003345", - "0000003360", - "0000003371", - "0000003381", - "0000003459", - "0000003509", - "0000003510", - "0000003564", - "0000003590", - "0000003591", - "0000003642", - "0000003664", - "0000003666", - "0000003712", - "0000003739", - "0000003777", - "0000003798", - "0000003807", - "0000003821", - "0000003831", - "0000003845", - "0000003847", - "0000003873", - "0000003913", - "0000003917", - "0000003925", - "0000003935", - "0000003955", - "0000004020", - "0000004050", - "0000004080", - "0000004088", - "0000004115", - "0000004136", - "0000004180", - "0000004186", - "0000004218", - "0000004253", - "0000004349", - "0000004419", - "0000004429", - "0000004442", - "0000004472", - "0000004533", - "0000004543", - "0000004629", - "0000004664", - "0000004684", - "0000004686", - "0000004697", - "0000004719", - "0000004720", - "0000004784", - "0000004785", - "0000004824", - "0000004833", - "0000004861", - "0000004930", - "0000004978", - "0000005025", - "0000005029", - "0000005039", - "0000005055", - "0000005060", - "0000005089", - "0000005091", - "0000005126", - "0000005137", - "0000005142", - "0000005200", - "0000005220", - "0000005222", - "0000005274", - "0000005283", - "0000005288", - "0000005342", - "0000005359", - "0000005360", - "0000005393", - "0000005446", - "0000005465", - "0000005469", - "0000005508", - "0000005586", - "0000005596", - "0000005613", - "0000005624", - "0000005630", - "0000005649", - "0000005654", - "0000005692", - "0000005723", - "0000005728", - "0000005759", - "0000005766", - "0000005775", - "0000005779", - "0000005808", - "0000005809", - "0000005810", - "0000005831", - "0000005842", - "0000005857", - "0000005954", - "0000005960", - "0000005969", - "0000005992", - "0000006038", - "0000006041", - "0000006077", - "0000006089", - "0000006101", - "0000006122", - "0000006151", - "0000006152", - "0000006183", - "0000006187", - "0000006213", - "0000006251", - "0000006255", - "0000006286", - "0000006352", - "0000006360", - "0000006376", - "0000006386", - "0000006429", - "0000006431", - "0000006451", - "0000006452", - "0000006494", - "0000006502", - "0000006527", - "0000006591", - "0000006613", - "0000006622", - "0000006624", - "0000006640", - "0000006675", - "0000006735", - "0000006747", - "0000006799", - "0000006838", - "0000006866", - "0000006868", - "0000006881", - "0000006918", - "0000006994", - "0000006996", - "0000007047", - "0000007052", - "0000007055", - "0000007077", - "0000007092", - "0000007097", - "0000007126", - "0000007192", - "0000007196", - "0000007220", - "0000007223", - "0000007268", - "0000007293", - "0000007315", - "0000007317", - "0000007321", - "0000007331", - "0000007355", - "0000007369", - "0000007392", - "0000007412", - "0000007427", - "0000007454", - "0000007485", - "0000007509", - "0000007512", - "0000007527", - "0000007552", - "0000007557", - "0000007566", - "0000007573", - "0000007576", - "0000007581", - "0000007598", - "0000007607", - "0000007646", - "0000007652", - "0000007683", - "0000007691", - "0000007693", - "0000007698", - "0000007712", - "0000007753", - "0000007797", - "0000007807", - "0000007820", - "0000007857", - "0000007879", - "0000007890", - "0000007937", - "0000007971", - "0000008001", - "0000008002", - "0000008130", - "0000008151", - "0000008174", - "0000008188", - "0000008195", - "0000008264", - "0000008303", - "0000008377", - "0000008441", - "0000008516", - "0000008522", - "0000008540", - "0000008541", - "0000008579", - "0000008592", - "0000008655", - "0000008703", - "0000008707", - "0000008716", - "0000008746", - "0000008826", - "0000008846", - "0000008896", - "0000008902", - "0000008907", - "0000008929", - "0000008933", - "0000008952", - "0000009037", - "0000009065", - "0000009067", - "0000009077", - "0000009092", - "0000009135", - "0000009154", - "0000009169", - "0000009225", - "0000009226", - "0000009237", - "0000009254", - "0000009277", - "0000009330", - "0000009332", - "0000009337", - "0000009352", - "0000009360", - "0000009378", - "0000009381", - "0000009390", - "0000009422", - "0000009427", - "0000009428", - "0000009498", - "0000009512", - "0000009534", - "0000009599", - "0000009607", - "0000009642", - "0000009719", - "0000009728", - "0000009774", - "0000009788", - "0000009790", - "0000009793", - "0000009807", - "0000009848", - "0000009853", - "0000009855", - "0000009867", - "0000009929", - "0000009995" - ], - "n_documents": 402, - "field_usage": [ - { - "field_name": "consolidated_text", - "source_type": "unified", - "usage_type": "text", - "n_non_null": 402, - "n_total": 402, - "coverage": 1.0 - }, - { - "field_name": "order_to_delivery_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 390, - "n_total": 402, - "coverage": 0.9701492537313433 - }, - { - "field_name": "delivery_to_invoice_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 0, - "n_total": 402, - "coverage": 0.0 - }, - { - "field_name": "order_to_invoice_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 375, - "n_total": 402, - "coverage": 0.9328358208955224 - }, - { - "field_name": "delay_from_requested_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 0, - "n_total": 402, - "coverage": 0.0 - } - ], - "row_counts": { - "total_documents": 10000, - "cluster_documents": 402 - }, - "sampling_warnings": [], - "reproducibility": { - "random_seed": 42, - "clustering_algorithm": "kmeans", - "embedding_model": "tfidf", - "n_clusters": 8, - "min_cluster_size": 5, - "delay_threshold_days": 7, - "analysis_timestamp": "2025-12-27T23:53:08.552691Z", - "package_version": "0.1.0", - "parameters": {} - }, - "source_files": [ - "../synthetic-data/sample_output/orders.json", - "../synthetic-data/sample_output/deliveries.json", - "../synthetic-data/sample_output/invoices.json", - "../synthetic-data/sample_output/doc_flows.json", - "../synthetic-data/sample_output/customers.json", - "../synthetic-data/sample_output/materials.json" - ], - "has_warnings": false, - "validation_issues": [ - "Low coverage (0%) for field delivery_to_invoice_days", - "Low coverage (0%) for field delay_from_requested_days" - ] - } - }, - { - "card_id": "PAT-4DC2ADD9", - "doc_keys": [ - "0000000018", - "0000000067", - "0000000123", - "0000000130", - "0000000182", - "0000000223", - "0000000258", - "0000000288", - "0000000321", - "0000000337", - "0000000351", - "0000000361", - "0000000476", - "0000000495", - "0000000497", - "0000000511", - "0000000600", - "0000000609", - "0000000640", - "0000000645", - "0000000658", - "0000000742", - "0000000780", - "0000000904", - "0000000914", - "0000001006", - "0000001024", - "0000001100", - "0000001301", - "0000001311", - "0000001371", - "0000001386", - "0000001551", - "0000001564", - "0000001569", - "0000001575", - "0000001649", - "0000001685", - "0000001727", - "0000001733", - "0000001740", - "0000001846", - "0000001908", - "0000001945", - "0000001981", - "0000002023", - "0000002105", - "0000002118", - "0000002172", - "0000002176", - "0000002201", - "0000002250", - "0000002298", - "0000002372", - "0000002478", - "0000002509", - "0000002643", - "0000002663", - "0000002740", - "0000002759", - "0000002790", - "0000002908", - "0000002910", - "0000002958", - "0000002997", - "0000003080", - "0000003133", - "0000003185", - "0000003193", - "0000003215", - "0000003245", - "0000003299", - "0000003325", - "0000003408", - "0000003451", - "0000003462", - "0000003707", - "0000003708", - "0000003720", - "0000003744", - "0000003749", - "0000003768", - "0000003772", - "0000003781", - "0000003810", - "0000003911", - "0000003965", - "0000004153", - "0000004183", - "0000004265", - "0000004295", - "0000004368", - "0000004499", - "0000004528", - "0000004657", - "0000004658", - "0000004682", - "0000004786", - "0000004812", - "0000004836", - "0000004929", - "0000004953", - "0000004985", - "0000005064", - "0000005201", - "0000005215", - "0000005255", - "0000005329", - "0000005379", - "0000005384", - "0000005388", - "0000005438", - "0000005487", - "0000005497", - "0000005601", - "0000005795", - "0000005850", - "0000005911", - "0000005932", - "0000005937", - "0000005984", - "0000006092", - "0000006100", - "0000006201", - "0000006334", - "0000006342", - "0000006367", - "0000006397", - "0000006433", - "0000006504", - "0000006669", - "0000006777", - "0000006873", - "0000006883", - "0000007142", - "0000007235", - "0000007244", - "0000007256", - "0000007310", - "0000007339", - "0000007378", - "0000007387", - "0000007396", - "0000007444", - "0000007453", - "0000007502", - "0000007531", - "0000007541", - "0000007635", - "0000007685", - "0000007748", - "0000007806", - "0000007812", - "0000007832", - "0000007848", - "0000007869", - "0000007924", - "0000008035", - "0000008059", - "0000008101", - "0000008185", - "0000008343", - "0000008467", - "0000008491", - "0000008585", - "0000008629", - "0000008690", - "0000008742", - "0000008781", - "0000008833", - "0000008837", - "0000008843", - "0000008928", - "0000008966", - "0000009012", - "0000009084", - "0000009096", - "0000009230", - "0000009240", - "0000009415", - "0000009423", - "0000009442", - "0000009468", - "0000009601", - "0000009611", - "0000009612", - "0000009662", - "0000009671", - "0000009703", - "0000009763", - "0000009792", - "0000009830", - "0000009871", - "0000009893", - "0000009922" - ], - "fields_used": [ - "consolidated_text", - "order_to_delivery_days", - "delivery_to_invoice_days", - "order_to_invoice_days", - "delay_from_requested_days" - ], - "sample_size": 195, - "total_population": 10000, - "full_evidence": { - "doc_keys": [ - "0000000018", - "0000000067", - "0000000123", - "0000000130", - "0000000182", - "0000000223", - "0000000258", - "0000000288", - "0000000321", - "0000000337", - "0000000351", - "0000000361", - "0000000476", - "0000000495", - "0000000497", - "0000000511", - "0000000600", - "0000000609", - "0000000640", - "0000000645", - "0000000658", - "0000000742", - "0000000780", - "0000000904", - "0000000914", - "0000001006", - "0000001024", - "0000001100", - "0000001301", - "0000001311", - "0000001371", - "0000001386", - "0000001551", - "0000001564", - "0000001569", - "0000001575", - "0000001649", - "0000001685", - "0000001727", - "0000001733", - "0000001740", - "0000001846", - "0000001908", - "0000001945", - "0000001981", - "0000002023", - "0000002105", - "0000002118", - "0000002172", - "0000002176", - "0000002201", - "0000002250", - "0000002298", - "0000002372", - "0000002478", - "0000002509", - "0000002643", - "0000002663", - "0000002740", - "0000002759", - "0000002790", - "0000002908", - "0000002910", - "0000002958", - "0000002997", - "0000003080", - "0000003133", - "0000003185", - "0000003193", - "0000003215", - "0000003245", - "0000003299", - "0000003325", - "0000003408", - "0000003451", - "0000003462", - "0000003707", - "0000003708", - "0000003720", - "0000003744", - "0000003749", - "0000003768", - "0000003772", - "0000003781", - "0000003810", - "0000003911", - "0000003965", - "0000004153", - "0000004183", - "0000004265", - "0000004295", - "0000004368", - "0000004499", - "0000004528", - "0000004657", - "0000004658", - "0000004682", - "0000004786", - "0000004812", - "0000004836", - "0000004929", - "0000004953", - "0000004985", - "0000005064", - "0000005201", - "0000005215", - "0000005255", - "0000005329", - "0000005379", - "0000005384", - "0000005388", - "0000005438", - "0000005487", - "0000005497", - "0000005601", - "0000005795", - "0000005850", - "0000005911", - "0000005932", - "0000005937", - "0000005984", - "0000006092", - "0000006100", - "0000006201", - "0000006334", - "0000006342", - "0000006367", - "0000006397", - "0000006433", - "0000006504", - "0000006669", - "0000006777", - "0000006873", - "0000006883", - "0000007142", - "0000007235", - "0000007244", - "0000007256", - "0000007310", - "0000007339", - "0000007378", - "0000007387", - "0000007396", - "0000007444", - "0000007453", - "0000007502", - "0000007531", - "0000007541", - "0000007635", - "0000007685", - "0000007748", - "0000007806", - "0000007812", - "0000007832", - "0000007848", - "0000007869", - "0000007924", - "0000008035", - "0000008059", - "0000008101", - "0000008185", - "0000008343", - "0000008467", - "0000008491", - "0000008585", - "0000008629", - "0000008690", - "0000008742", - "0000008781", - "0000008833", - "0000008837", - "0000008843", - "0000008928", - "0000008966", - "0000009012", - "0000009084", - "0000009096", - "0000009230", - "0000009240", - "0000009415", - "0000009423", - "0000009442", - "0000009468", - "0000009601", - "0000009611", - "0000009612", - "0000009662", - "0000009671", - "0000009703", - "0000009763", - "0000009792", - "0000009830", - "0000009871", - "0000009893", - "0000009922" - ], - "n_documents": 195, - "field_usage": [ - { - "field_name": "consolidated_text", - "source_type": "unified", - "usage_type": "text", - "n_non_null": 195, - "n_total": 195, - "coverage": 1.0 - }, - { - "field_name": "order_to_delivery_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 179, - "n_total": 195, - "coverage": 0.9179487179487179 - }, - { - "field_name": "delivery_to_invoice_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 0, - "n_total": 195, - "coverage": 0.0 - }, - { - "field_name": "order_to_invoice_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 176, - "n_total": 195, - "coverage": 0.9025641025641026 - }, - { - "field_name": "delay_from_requested_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 0, - "n_total": 195, - "coverage": 0.0 - } - ], - "row_counts": { - "total_documents": 10000, - "cluster_documents": 195 - }, - "sampling_warnings": [], - "reproducibility": { - "random_seed": 42, - "clustering_algorithm": "kmeans", - "embedding_model": "tfidf", - "n_clusters": 8, - "min_cluster_size": 5, - "delay_threshold_days": 7, - "analysis_timestamp": "2025-12-27T23:53:08.556665Z", - "package_version": "0.1.0", - "parameters": {} - }, - "source_files": [ - "../synthetic-data/sample_output/orders.json", - "../synthetic-data/sample_output/deliveries.json", - "../synthetic-data/sample_output/invoices.json", - "../synthetic-data/sample_output/doc_flows.json", - "../synthetic-data/sample_output/customers.json", - "../synthetic-data/sample_output/materials.json" - ], - "has_warnings": false, - "validation_issues": [ - "Low coverage (0%) for field delivery_to_invoice_days", - "Low coverage (0%) for field delay_from_requested_days" - ] - } - }, - { - "card_id": "PAT-8BB0F9C7", - "doc_keys": [ - "0000000100", - "0000000112", - "0000000148", - "0000000163", - "0000000219", - "0000000246", - "0000000253", - "0000000331", - "0000000367", - "0000000427", - "0000000439", - "0000000503", - "0000000572", - "0000000595", - "0000000599", - "0000000642", - "0000000643", - "0000000676", - "0000000702", - "0000000730", - "0000000809", - "0000000831", - "0000000842", - "0000000852", - "0000000889", - "0000000933", - "0000000947", - "0000000980", - "0000001002", - "0000001023", - "0000001077", - "0000001137", - "0000001157", - "0000001186", - "0000001228", - "0000001260", - "0000001272", - "0000001288", - "0000001299", - "0000001361", - "0000001411", - "0000001451", - "0000001454", - "0000001472", - "0000001486", - "0000001533", - "0000001553", - "0000001560", - "0000001601", - "0000001605", - "0000001613", - "0000001645", - "0000001650", - "0000001745", - "0000001787", - "0000001857", - "0000001876", - "0000001896", - "0000001898", - "0000001932", - "0000001933", - "0000002008", - "0000002151", - "0000002165", - "0000002182", - "0000002192", - "0000002217", - "0000002282", - "0000002286", - "0000002306", - "0000002324", - "0000002467", - "0000002521", - "0000002553", - "0000002566", - "0000002581", - "0000002583", - "0000002588", - "0000002666", - "0000002696", - "0000002703", - "0000002733", - "0000002826", - "0000002863", - "0000002876", - "0000002890", - "0000002904", - "0000002953", - "0000003048", - "0000003067", - "0000003086", - "0000003132", - "0000003161", - "0000003165", - "0000003204", - "0000003319", - "0000003362", - "0000003393", - "0000003419", - "0000003430", - "0000003446", - "0000003453", - "0000003469", - "0000003483", - "0000003488", - "0000003504", - "0000003514", - "0000003515", - "0000003552", - "0000003557", - "0000003567", - "0000003613", - "0000003614", - "0000003617", - "0000003650", - "0000003660", - "0000003668", - "0000003686", - "0000003706", - "0000003823", - "0000003830", - "0000003849", - "0000003858", - "0000003868", - "0000003890", - "0000003912", - "0000003931", - "0000003957", - "0000003979", - "0000004000", - "0000004003", - "0000004008", - "0000004023", - "0000004051", - "0000004057", - "0000004070", - "0000004075", - "0000004079", - "0000004119", - "0000004139", - "0000004166", - "0000004167", - "0000004192", - "0000004223", - "0000004227", - "0000004287", - "0000004302", - "0000004362", - "0000004382", - "0000004395", - "0000004435", - "0000004456", - "0000004509", - "0000004546", - "0000004565", - "0000004578", - "0000004687", - "0000004763", - "0000004769", - "0000004799", - "0000004841", - "0000004850", - "0000004859", - "0000004863", - "0000004867", - "0000004869", - "0000004890", - "0000004911", - "0000004942", - "0000004947", - "0000004970", - "0000005007", - "0000005017", - "0000005021", - "0000005022", - "0000005046", - "0000005051", - "0000005114", - "0000005139", - "0000005143", - "0000005164", - "0000005167", - "0000005194", - "0000005207", - "0000005211", - "0000005245", - "0000005265", - "0000005322", - "0000005323", - "0000005444", - "0000005462", - "0000005476", - "0000005575", - "0000005606", - "0000005669", - "0000005684", - "0000005697", - "0000005722", - "0000005771", - "0000005776", - "0000005789", - "0000005798", - "0000005869", - "0000005875", - "0000005938", - "0000006022", - "0000006026", - "0000006028", - "0000006052", - "0000006066", - "0000006080", - "0000006095", - "0000006121", - "0000006127", - "0000006139", - "0000006195", - "0000006214", - "0000006264", - "0000006277", - "0000006297", - "0000006362", - "0000006366", - "0000006370", - "0000006403", - "0000006408", - "0000006411", - "0000006466", - "0000006468", - "0000006493", - "0000006497", - "0000006500", - "0000006518", - "0000006544", - "0000006600", - "0000006666", - "0000006667", - "0000006704", - "0000006734", - "0000006800", - "0000006819", - "0000006837", - "0000006882", - "0000006906", - "0000006917", - "0000006924", - "0000006945", - "0000006968", - "0000006990", - "0000007004", - "0000007076", - "0000007080", - "0000007178", - "0000007210", - "0000007238", - "0000007262", - "0000007280", - "0000007298", - "0000007305", - "0000007364", - "0000007379", - "0000007382", - "0000007394", - "0000007441", - "0000007458", - "0000007459", - "0000007464", - "0000007465", - "0000007515", - "0000007521", - "0000007530", - "0000007537", - "0000007545", - "0000007604", - "0000007614", - "0000007626", - "0000007640", - "0000007680", - "0000007696", - "0000007701", - "0000007707", - "0000007732", - "0000007738", - "0000007773", - "0000007800", - "0000007813", - "0000007817", - "0000007831", - "0000007853", - "0000007886", - "0000008007", - "0000008021", - "0000008072", - "0000008107", - "0000008128", - "0000008146", - "0000008167", - "0000008232", - "0000008282", - "0000008314", - "0000008324", - "0000008363", - "0000008366", - "0000008404", - "0000008431", - "0000008451", - "0000008475", - "0000008533", - "0000008562", - "0000008583", - "0000008613", - "0000008654", - "0000008702", - "0000008709", - "0000008727", - "0000008730", - "0000008745", - "0000008755", - "0000008780", - "0000008827", - "0000008942", - "0000008948", - "0000008973", - "0000008988", - "0000009004", - "0000009024", - "0000009044", - "0000009050", - "0000009083", - "0000009147", - "0000009149", - "0000009153", - "0000009167", - "0000009209", - "0000009229", - "0000009262", - "0000009297", - "0000009406", - "0000009435", - "0000009582", - "0000009621", - "0000009630", - "0000009645", - "0000009655", - "0000009668", - "0000009672", - "0000009679", - "0000009714", - "0000009724", - "0000009739", - "0000009746", - "0000009784", - "0000009816", - "0000009846", - "0000009879", - "0000009888", - "0000009895", - "0000009904", - "0000009926", - "0000009955", - "0000009961", - "0000009986" - ], - "fields_used": [ - "consolidated_text", - "order_to_delivery_days", - "delivery_to_invoice_days", - "order_to_invoice_days", - "delay_from_requested_days" - ], - "sample_size": 361, - "total_population": 10000, - "full_evidence": { - "doc_keys": [ - "0000000100", - "0000000112", - "0000000148", - "0000000163", - "0000000219", - "0000000246", - "0000000253", - "0000000331", - "0000000367", - "0000000427", - "0000000439", - "0000000503", - "0000000572", - "0000000595", - "0000000599", - "0000000642", - "0000000643", - "0000000676", - "0000000702", - "0000000730", - "0000000809", - "0000000831", - "0000000842", - "0000000852", - "0000000889", - "0000000933", - "0000000947", - "0000000980", - "0000001002", - "0000001023", - "0000001077", - "0000001137", - "0000001157", - "0000001186", - "0000001228", - "0000001260", - "0000001272", - "0000001288", - "0000001299", - "0000001361", - "0000001411", - "0000001451", - "0000001454", - "0000001472", - "0000001486", - "0000001533", - "0000001553", - "0000001560", - "0000001601", - "0000001605", - "0000001613", - "0000001645", - "0000001650", - "0000001745", - "0000001787", - "0000001857", - "0000001876", - "0000001896", - "0000001898", - "0000001932", - "0000001933", - "0000002008", - "0000002151", - "0000002165", - "0000002182", - "0000002192", - "0000002217", - "0000002282", - "0000002286", - "0000002306", - "0000002324", - "0000002467", - "0000002521", - "0000002553", - "0000002566", - "0000002581", - "0000002583", - "0000002588", - "0000002666", - "0000002696", - "0000002703", - "0000002733", - "0000002826", - "0000002863", - "0000002876", - "0000002890", - "0000002904", - "0000002953", - "0000003048", - "0000003067", - "0000003086", - "0000003132", - "0000003161", - "0000003165", - "0000003204", - "0000003319", - "0000003362", - "0000003393", - "0000003419", - "0000003430", - "0000003446", - "0000003453", - "0000003469", - "0000003483", - "0000003488", - "0000003504", - "0000003514", - "0000003515", - "0000003552", - "0000003557", - "0000003567", - "0000003613", - "0000003614", - "0000003617", - "0000003650", - "0000003660", - "0000003668", - "0000003686", - "0000003706", - "0000003823", - "0000003830", - "0000003849", - "0000003858", - "0000003868", - "0000003890", - "0000003912", - "0000003931", - "0000003957", - "0000003979", - "0000004000", - "0000004003", - "0000004008", - "0000004023", - "0000004051", - "0000004057", - "0000004070", - "0000004075", - "0000004079", - "0000004119", - "0000004139", - "0000004166", - "0000004167", - "0000004192", - "0000004223", - "0000004227", - "0000004287", - "0000004302", - "0000004362", - "0000004382", - "0000004395", - "0000004435", - "0000004456", - "0000004509", - "0000004546", - "0000004565", - "0000004578", - "0000004687", - "0000004763", - "0000004769", - "0000004799", - "0000004841", - "0000004850", - "0000004859", - "0000004863", - "0000004867", - "0000004869", - "0000004890", - "0000004911", - "0000004942", - "0000004947", - "0000004970", - "0000005007", - "0000005017", - "0000005021", - "0000005022", - "0000005046", - "0000005051", - "0000005114", - "0000005139", - "0000005143", - "0000005164", - "0000005167", - "0000005194", - "0000005207", - "0000005211", - "0000005245", - "0000005265", - "0000005322", - "0000005323", - "0000005444", - "0000005462", - "0000005476", - "0000005575", - "0000005606", - "0000005669", - "0000005684", - "0000005697", - "0000005722", - "0000005771", - "0000005776", - "0000005789", - "0000005798", - "0000005869", - "0000005875", - "0000005938", - "0000006022", - "0000006026", - "0000006028", - "0000006052", - "0000006066", - "0000006080", - "0000006095", - "0000006121", - "0000006127", - "0000006139", - "0000006195", - "0000006214", - "0000006264", - "0000006277", - "0000006297", - "0000006362", - "0000006366", - "0000006370", - "0000006403", - "0000006408", - "0000006411", - "0000006466", - "0000006468", - "0000006493", - "0000006497", - "0000006500", - "0000006518", - "0000006544", - "0000006600", - "0000006666", - "0000006667", - "0000006704", - "0000006734", - "0000006800", - "0000006819", - "0000006837", - "0000006882", - "0000006906", - "0000006917", - "0000006924", - "0000006945", - "0000006968", - "0000006990", - "0000007004", - "0000007076", - "0000007080", - "0000007178", - "0000007210", - "0000007238", - "0000007262", - "0000007280", - "0000007298", - "0000007305", - "0000007364", - "0000007379", - "0000007382", - "0000007394", - "0000007441", - "0000007458", - "0000007459", - "0000007464", - "0000007465", - "0000007515", - "0000007521", - "0000007530", - "0000007537", - "0000007545", - "0000007604", - "0000007614", - "0000007626", - "0000007640", - "0000007680", - "0000007696", - "0000007701", - "0000007707", - "0000007732", - "0000007738", - "0000007773", - "0000007800", - "0000007813", - "0000007817", - "0000007831", - "0000007853", - "0000007886", - "0000008007", - "0000008021", - "0000008072", - "0000008107", - "0000008128", - "0000008146", - "0000008167", - "0000008232", - "0000008282", - "0000008314", - "0000008324", - "0000008363", - "0000008366", - "0000008404", - "0000008431", - "0000008451", - "0000008475", - "0000008533", - "0000008562", - "0000008583", - "0000008613", - "0000008654", - "0000008702", - "0000008709", - "0000008727", - "0000008730", - "0000008745", - "0000008755", - "0000008780", - "0000008827", - "0000008942", - "0000008948", - "0000008973", - "0000008988", - "0000009004", - "0000009024", - "0000009044", - "0000009050", - "0000009083", - "0000009147", - "0000009149", - "0000009153", - "0000009167", - "0000009209", - "0000009229", - "0000009262", - "0000009297", - "0000009406", - "0000009435", - "0000009582", - "0000009621", - "0000009630", - "0000009645", - "0000009655", - "0000009668", - "0000009672", - "0000009679", - "0000009714", - "0000009724", - "0000009739", - "0000009746", - "0000009784", - "0000009816", - "0000009846", - "0000009879", - "0000009888", - "0000009895", - "0000009904", - "0000009926", - "0000009955", - "0000009961", - "0000009986" - ], - "n_documents": 361, - "field_usage": [ - { - "field_name": "consolidated_text", - "source_type": "unified", - "usage_type": "text", - "n_non_null": 361, - "n_total": 361, - "coverage": 1.0 - }, - { - "field_name": "order_to_delivery_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 344, - "n_total": 361, - "coverage": 0.9529085872576177 - }, - { - "field_name": "delivery_to_invoice_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 0, - "n_total": 361, - "coverage": 0.0 - }, - { - "field_name": "order_to_invoice_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 330, - "n_total": 361, - "coverage": 0.9141274238227147 - }, - { - "field_name": "delay_from_requested_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 0, - "n_total": 361, - "coverage": 0.0 - } - ], - "row_counts": { - "total_documents": 10000, - "cluster_documents": 361 - }, - "sampling_warnings": [], - "reproducibility": { - "random_seed": 42, - "clustering_algorithm": "kmeans", - "embedding_model": "tfidf", - "n_clusters": 8, - "min_cluster_size": 5, - "delay_threshold_days": 7, - "analysis_timestamp": "2025-12-27T23:53:08.568445Z", - "package_version": "0.1.0", - "parameters": {} - }, - "source_files": [ - "../synthetic-data/sample_output/orders.json", - "../synthetic-data/sample_output/deliveries.json", - "../synthetic-data/sample_output/invoices.json", - "../synthetic-data/sample_output/doc_flows.json", - "../synthetic-data/sample_output/customers.json", - "../synthetic-data/sample_output/materials.json" - ], - "has_warnings": false, - "validation_issues": [ - "Low coverage (0%) for field delivery_to_invoice_days", - "Low coverage (0%) for field delay_from_requested_days" - ] - } - }, - { - "card_id": "PAT-119F3CBF", - "doc_keys": [ - "0000000003", - "0000000046", - "0000000082", - "0000000094", - "0000000107", - "0000000197", - "0000000268", - "0000000272", - "0000000285", - "0000000663", - "0000000664", - "0000000724", - "0000000752", - "0000000796", - "0000000850", - "0000000857", - "0000000913", - "0000000940", - "0000000950", - "0000000971", - "0000000981", - "0000001000", - "0000001075", - "0000001078", - "0000001102", - "0000001142", - "0000001174", - "0000001178", - "0000001284", - "0000001341", - "0000001349", - "0000001367", - "0000001400", - "0000001402", - "0000001416", - "0000001424", - "0000001485", - "0000001504", - "0000001545", - "0000001549", - "0000001580", - "0000001609", - "0000001616", - "0000001652", - "0000001671", - "0000001674", - "0000001700", - "0000001711", - "0000001722", - "0000001871", - "0000001989", - "0000002060", - "0000002066", - "0000002112", - "0000002163", - "0000002200", - "0000002204", - "0000002251", - "0000002288", - "0000002354", - "0000002423", - "0000002424", - "0000002551", - "0000002556", - "0000002622", - "0000002675", - "0000002699", - "0000002775", - "0000002798", - "0000002801", - "0000002818", - "0000002849", - "0000002938", - "0000002989", - "0000002990", - "0000003008", - "0000003030", - "0000003069", - "0000003075", - "0000003142", - "0000003170", - "0000003171", - "0000003267", - "0000003304", - "0000003333", - "0000003342", - "0000003365", - "0000003403", - "0000003424", - "0000003490", - "0000003550", - "0000003608", - "0000003611", - "0000003623", - "0000003634", - "0000003640", - "0000003652", - "0000003657", - "0000003802", - "0000003833", - "0000003850", - "0000003875", - "0000003956", - "0000004093", - "0000004147", - "0000004196", - "0000004285", - "0000004296", - "0000004361", - "0000004375", - "0000004389", - "0000004465", - "0000004501", - "0000004506", - "0000004538", - "0000004582", - "0000004601", - "0000004649", - "0000004659", - "0000004702", - "0000004710", - "0000004729", - "0000004773", - "0000004779", - "0000004842", - "0000004935", - "0000004996", - "0000005004", - "0000005068", - "0000005078", - "0000005096", - "0000005098", - "0000005115", - "0000005144", - "0000005149", - "0000005150", - "0000005225", - "0000005226", - "0000005309", - "0000005331", - "0000005346", - "0000005362", - "0000005367", - "0000005372", - "0000005377", - "0000005404", - "0000005423", - "0000005450", - "0000005547", - "0000005600", - "0000005640", - "0000005673", - "0000005676", - "0000005702", - "0000005741", - "0000005784", - "0000005793", - "0000005877", - "0000005935", - "0000005944", - "0000005973", - "0000006023", - "0000006069", - "0000006075", - "0000006083", - "0000006137", - "0000006166", - "0000006252", - "0000006314", - "0000006368", - "0000006372", - "0000006384", - "0000006424", - "0000006445", - "0000006478", - "0000006482", - "0000006501", - "0000006530", - "0000006532", - "0000006547", - "0000006573", - "0000006709", - "0000006717", - "0000006724", - "0000006746", - "0000006865", - "0000006916", - "0000006938", - "0000006949", - "0000006951", - "0000006974", - "0000007053", - "0000007168", - "0000007185", - "0000007226", - "0000007304", - "0000007309", - "0000007334", - "0000007341", - "0000007448", - "0000007475", - "0000007505", - "0000007572", - "0000007582", - "0000007630", - "0000007655", - "0000007672", - "0000007703", - "0000007713", - "0000007746", - "0000007751", - "0000007776", - "0000007842", - "0000007903", - "0000007907", - "0000007910", - "0000007927", - "0000007946", - "0000007952", - "0000007961", - "0000007982", - "0000008055", - "0000008088", - "0000008110", - "0000008118", - "0000008126", - "0000008127", - "0000008156", - "0000008163", - "0000008216", - "0000008222", - "0000008249", - "0000008255", - "0000008308", - "0000008335", - "0000008362", - "0000008449", - "0000008486", - "0000008521", - "0000008546", - "0000008623", - "0000008668", - "0000008693", - "0000008714", - "0000008721", - "0000008726", - "0000008760", - "0000008767", - "0000008784", - "0000008849", - "0000008850", - "0000008864", - "0000008877", - "0000008897", - "0000008903", - "0000008917", - "0000008930", - "0000008974", - "0000008990", - "0000009134", - "0000009143", - "0000009176", - "0000009244", - "0000009270", - "0000009310", - "0000009316", - "0000009317", - "0000009358", - "0000009362", - "0000009375", - "0000009472", - "0000009483", - "0000009493", - "0000009518", - "0000009527", - "0000009533", - "0000009558", - "0000009610", - "0000009627", - "0000009641", - "0000009686", - "0000009711", - "0000009796", - "0000009839", - "0000009843", - "0000009869", - "0000009951", - "0000009976" - ], - "fields_used": [ - "consolidated_text", - "order_to_delivery_days", - "delivery_to_invoice_days", - "order_to_invoice_days", - "delay_from_requested_days" - ], - "sample_size": 288, - "total_population": 10000, - "full_evidence": { - "doc_keys": [ - "0000000003", - "0000000046", - "0000000082", - "0000000094", - "0000000107", - "0000000197", - "0000000268", - "0000000272", - "0000000285", - "0000000663", - "0000000664", - "0000000724", - "0000000752", - "0000000796", - "0000000850", - "0000000857", - "0000000913", - "0000000940", - "0000000950", - "0000000971", - "0000000981", - "0000001000", - "0000001075", - "0000001078", - "0000001102", - "0000001142", - "0000001174", - "0000001178", - "0000001284", - "0000001341", - "0000001349", - "0000001367", - "0000001400", - "0000001402", - "0000001416", - "0000001424", - "0000001485", - "0000001504", - "0000001545", - "0000001549", - "0000001580", - "0000001609", - "0000001616", - "0000001652", - "0000001671", - "0000001674", - "0000001700", - "0000001711", - "0000001722", - "0000001871", - "0000001989", - "0000002060", - "0000002066", - "0000002112", - "0000002163", - "0000002200", - "0000002204", - "0000002251", - "0000002288", - "0000002354", - "0000002423", - "0000002424", - "0000002551", - "0000002556", - "0000002622", - "0000002675", - "0000002699", - "0000002775", - "0000002798", - "0000002801", - "0000002818", - "0000002849", - "0000002938", - "0000002989", - "0000002990", - "0000003008", - "0000003030", - "0000003069", - "0000003075", - "0000003142", - "0000003170", - "0000003171", - "0000003267", - "0000003304", - "0000003333", - "0000003342", - "0000003365", - "0000003403", - "0000003424", - "0000003490", - "0000003550", - "0000003608", - "0000003611", - "0000003623", - "0000003634", - "0000003640", - "0000003652", - "0000003657", - "0000003802", - "0000003833", - "0000003850", - "0000003875", - "0000003956", - "0000004093", - "0000004147", - "0000004196", - "0000004285", - "0000004296", - "0000004361", - "0000004375", - "0000004389", - "0000004465", - "0000004501", - "0000004506", - "0000004538", - "0000004582", - "0000004601", - "0000004649", - "0000004659", - "0000004702", - "0000004710", - "0000004729", - "0000004773", - "0000004779", - "0000004842", - "0000004935", - "0000004996", - "0000005004", - "0000005068", - "0000005078", - "0000005096", - "0000005098", - "0000005115", - "0000005144", - "0000005149", - "0000005150", - "0000005225", - "0000005226", - "0000005309", - "0000005331", - "0000005346", - "0000005362", - "0000005367", - "0000005372", - "0000005377", - "0000005404", - "0000005423", - "0000005450", - "0000005547", - "0000005600", - "0000005640", - "0000005673", - "0000005676", - "0000005702", - "0000005741", - "0000005784", - "0000005793", - "0000005877", - "0000005935", - "0000005944", - "0000005973", - "0000006023", - "0000006069", - "0000006075", - "0000006083", - "0000006137", - "0000006166", - "0000006252", - "0000006314", - "0000006368", - "0000006372", - "0000006384", - "0000006424", - "0000006445", - "0000006478", - "0000006482", - "0000006501", - "0000006530", - "0000006532", - "0000006547", - "0000006573", - "0000006709", - "0000006717", - "0000006724", - "0000006746", - "0000006865", - "0000006916", - "0000006938", - "0000006949", - "0000006951", - "0000006974", - "0000007053", - "0000007168", - "0000007185", - "0000007226", - "0000007304", - "0000007309", - "0000007334", - "0000007341", - "0000007448", - "0000007475", - "0000007505", - "0000007572", - "0000007582", - "0000007630", - "0000007655", - "0000007672", - "0000007703", - "0000007713", - "0000007746", - "0000007751", - "0000007776", - "0000007842", - "0000007903", - "0000007907", - "0000007910", - "0000007927", - "0000007946", - "0000007952", - "0000007961", - "0000007982", - "0000008055", - "0000008088", - "0000008110", - "0000008118", - "0000008126", - "0000008127", - "0000008156", - "0000008163", - "0000008216", - "0000008222", - "0000008249", - "0000008255", - "0000008308", - "0000008335", - "0000008362", - "0000008449", - "0000008486", - "0000008521", - "0000008546", - "0000008623", - "0000008668", - "0000008693", - "0000008714", - "0000008721", - "0000008726", - "0000008760", - "0000008767", - "0000008784", - "0000008849", - "0000008850", - "0000008864", - "0000008877", - "0000008897", - "0000008903", - "0000008917", - "0000008930", - "0000008974", - "0000008990", - "0000009134", - "0000009143", - "0000009176", - "0000009244", - "0000009270", - "0000009310", - "0000009316", - "0000009317", - "0000009358", - "0000009362", - "0000009375", - "0000009472", - "0000009483", - "0000009493", - "0000009518", - "0000009527", - "0000009533", - "0000009558", - "0000009610", - "0000009627", - "0000009641", - "0000009686", - "0000009711", - "0000009796", - "0000009839", - "0000009843", - "0000009869", - "0000009951", - "0000009976" - ], - "n_documents": 288, - "field_usage": [ - { - "field_name": "consolidated_text", - "source_type": "unified", - "usage_type": "text", - "n_non_null": 288, - "n_total": 288, - "coverage": 1.0 - }, - { - "field_name": "order_to_delivery_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 281, - "n_total": 288, - "coverage": 0.9756944444444444 - }, - { - "field_name": "delivery_to_invoice_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 0, - "n_total": 288, - "coverage": 0.0 - }, - { - "field_name": "order_to_invoice_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 274, - "n_total": 288, - "coverage": 0.9513888888888888 - }, - { - "field_name": "delay_from_requested_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 0, - "n_total": 288, - "coverage": 0.0 - } - ], - "row_counts": { - "total_documents": 10000, - "cluster_documents": 288 - }, - "sampling_warnings": [], - "reproducibility": { - "random_seed": 42, - "clustering_algorithm": "kmeans", - "embedding_model": "tfidf", - "n_clusters": 8, - "min_cluster_size": 5, - "delay_threshold_days": 7, - "analysis_timestamp": "2025-12-27T23:53:08.574973Z", - "package_version": "0.1.0", - "parameters": {} - }, - "source_files": [ - "../synthetic-data/sample_output/orders.json", - "../synthetic-data/sample_output/deliveries.json", - "../synthetic-data/sample_output/invoices.json", - "../synthetic-data/sample_output/doc_flows.json", - "../synthetic-data/sample_output/customers.json", - "../synthetic-data/sample_output/materials.json" - ], - "has_warnings": false, - "validation_issues": [ - "Low coverage (0%) for field delivery_to_invoice_days", - "Low coverage (0%) for field delay_from_requested_days" - ] - } - } - ] -} \ No newline at end of file diff --git a/pattern-engine/test_output/pattern_cards.json b/pattern-engine/test_output/pattern_cards.json deleted file mode 100644 index eac01f6..0000000 --- a/pattern-engine/test_output/pattern_cards.json +++ /dev/null @@ -1,6900 +0,0 @@ -{ - "metadata": { - "generated_at": "2025-12-27T23:53:08.575107Z", - "seed": 42, - "mode": "shareable", - "n_cards": 8 - }, - "cards": [ - { - "id": "PAT-F22349FF", - "title": "Mgmt Approved / Mgmt / Approved", - "description": "Documents in this cluster frequently contain \"mgmt approved\", \"mgmt\", \"approved\". No statistically significant timing differences from baseline. Based on analysis of 347 documents.", - "top_phrases": [ - "mgmt approved", - "mgmt", - "approved", - "expedite mgmt approved", - "expedite mgmt", - "order mgmt approved", - "order mgmt", - "backorder mgmt approved", - "backorder mgmt", - "stock mgmt approved" - ], - "sample_snippets": [], - "occurrence": { - "count": 347, - "by_sales_org": { - "1000": 132, - "2000": 107, - "3000": 108 - }, - "by_customer_industry": { - "GOVERNMENT": 98, - "WHOLESALE": 84, - "RETAIL": 96, - "INDUSTRIAL": 69 - } - }, - "effect": {}, - "effects": [], - "confidence": "MEDIUM", - "confidence_score": 0.4, - "caveats": [ - "Observational analysis only; correlation does not imply causation.", - "Patterns based on text similarity; may not capture all relevant factors.", - "No statistically significant effects detected." - ], - "evidence": { - "doc_keys": [ - "0000000016", - "0000000045", - "0000000080", - "0000000113", - "0000000134", - "0000000185", - "0000000210", - "0000000239", - "0000000242", - "0000000252", - "0000000280", - "0000000316", - "0000000318", - "0000000323", - "0000000394", - "0000000423", - "0000000430", - "0000000451", - "0000000466", - "0000000490", - "0000000510", - "0000000525", - "0000000539", - "0000000590", - "0000000605", - "0000000653", - "0000000683", - "0000000694", - "0000000863", - "0000000866", - "0000000870", - "0000000880", - "0000000895", - "0000000935", - "0000000968", - "0000000970", - "0000000977", - "0000001015", - "0000001016", - "0000001060", - "0000001073", - "0000001082", - "0000001115", - "0000001119", - "0000001173", - "0000001195", - "0000001217", - "0000001248", - "0000001291", - "0000001297", - "0000001362", - "0000001405", - "0000001452", - "0000001493", - "0000001497", - "0000001506", - "0000001531", - "0000001591", - "0000001592", - "0000001635", - "0000001694", - "0000001779", - "0000001869", - "0000001946", - "0000001977", - "0000001979", - "0000002062", - "0000002091", - "0000002095", - "0000002257", - "0000002304", - "0000002397", - "0000002435", - "0000002442", - "0000002511", - "0000002513", - "0000002520", - "0000002534", - "0000002613", - "0000002619", - "0000002653", - "0000002704", - "0000002789", - "0000002795", - "0000002809", - "0000002812", - "0000002829", - "0000002847", - "0000002885", - "0000002914", - "0000002948", - "0000002978", - "0000002981", - "0000002983", - "0000003022", - "0000003029", - "0000003071", - "0000003125", - "0000003138", - "0000003148", - "0000003149", - "0000003182", - "0000003224", - "0000003239", - "0000003243", - "0000003256", - "0000003261", - "0000003273", - "0000003277", - "0000003303", - "0000003313", - "0000003316", - "0000003385", - "0000003415", - "0000003420", - "0000003428", - "0000003475", - "0000003525", - "0000003537", - "0000003541", - "0000003549", - "0000003577", - "0000003679", - "0000003682", - "0000003719", - "0000003721", - "0000003743", - "0000003782", - "0000003812", - "0000003814", - "0000003837", - "0000003848", - "0000003852", - "0000003859", - "0000003863", - "0000003907", - "0000003933", - "0000003938", - "0000004011", - "0000004046", - "0000004071", - "0000004082", - "0000004124", - "0000004130", - "0000004207", - "0000004212", - "0000004260", - "0000004286", - "0000004371", - "0000004396", - "0000004401", - "0000004404", - "0000004409", - "0000004445", - "0000004484", - "0000004550", - "0000004566", - "0000004590", - "0000004600", - "0000004627", - "0000004636", - "0000004642", - "0000004673", - "0000004688", - "0000004712", - "0000004739", - "0000004775", - "0000004815", - "0000004821", - "0000004864", - "0000004870", - "0000004889", - "0000004908", - "0000004912", - "0000004932", - "0000004948", - "0000004951", - "0000004976", - "0000005000", - "0000005016", - "0000005045", - "0000005048", - "0000005118", - "0000005162", - "0000005170", - "0000005186", - "0000005195", - "0000005202", - "0000005235", - "0000005239", - "0000005270", - "0000005294", - "0000005328", - "0000005355", - "0000005356", - "0000005376", - "0000005399", - "0000005416", - "0000005420", - "0000005436", - "0000005479", - "0000005492", - "0000005496", - "0000005536", - "0000005554", - "0000005568", - "0000005573", - "0000005582", - "0000005616", - "0000005682", - "0000005699", - "0000005764", - "0000005822", - "0000005823", - "0000005871", - "0000005897", - "0000005967", - "0000005971", - "0000006013", - "0000006025", - "0000006029", - "0000006030", - "0000006043", - "0000006063", - "0000006109", - "0000006128", - "0000006153", - "0000006158", - "0000006164", - "0000006205", - "0000006208", - "0000006238", - "0000006247", - "0000006299", - "0000006303", - "0000006350", - "0000006364", - "0000006404", - "0000006415", - "0000006423", - "0000006448", - "0000006486", - "0000006510", - "0000006514", - "0000006563", - "0000006593", - "0000006604", - "0000006612", - "0000006659", - "0000006702", - "0000006716", - "0000006728", - "0000006775", - "0000007002", - "0000007003", - "0000007030", - "0000007040", - "0000007128", - "0000007208", - "0000007264", - "0000007285", - "0000007295", - "0000007297", - "0000007302", - "0000007312", - "0000007373", - "0000007478", - "0000007517", - "0000007528", - "0000007535", - "0000007584", - "0000007596", - "0000007659", - "0000007684", - "0000007783", - "0000007798", - "0000007811", - "0000007819", - "0000007850", - "0000007864", - "0000007901", - "0000007974", - "0000007981", - "0000007987", - "0000007988", - "0000008000", - "0000008034", - "0000008071", - "0000008077", - "0000008102", - "0000008139", - "0000008175", - "0000008226", - "0000008258", - "0000008275", - "0000008289", - "0000008297", - "0000008305", - "0000008307", - "0000008373", - "0000008382", - "0000008411", - "0000008502", - "0000008534", - "0000008554", - "0000008584", - "0000008589", - "0000008590", - "0000008602", - "0000008656", - "0000008732", - "0000008756", - "0000008798", - "0000008815", - "0000008946", - "0000008955", - "0000008979", - "0000008998", - "0000009015", - "0000009031", - "0000009039", - "0000009071", - "0000009073", - "0000009075", - "0000009093", - "0000009102", - "0000009108", - "0000009141", - "0000009265", - "0000009311", - "0000009323", - "0000009351", - "0000009391", - "0000009437", - "0000009466", - "0000009469", - "0000009471", - "0000009543", - "0000009618", - "0000009669", - "0000009689", - "0000009759", - "0000009773", - "0000009832", - "0000009849", - "0000009917", - "0000009950" - ], - "fields_used": [ - "consolidated_text", - "order_to_delivery_days", - "delivery_to_invoice_days", - "order_to_invoice_days", - "delay_from_requested_days" - ], - "sample_size": 347, - "total_population": 10000 - }, - "cluster_id": "0", - "created_at": "2025-12-27T23:53:08.526044Z", - "is_notable": false, - "full_evidence": { - "doc_keys": [ - "0000000016", - "0000000045", - "0000000080", - "0000000113", - "0000000134", - "0000000185", - "0000000210", - "0000000239", - "0000000242", - "0000000252", - "0000000280", - "0000000316", - "0000000318", - "0000000323", - "0000000394", - "0000000423", - "0000000430", - "0000000451", - "0000000466", - "0000000490", - "0000000510", - "0000000525", - "0000000539", - "0000000590", - "0000000605", - "0000000653", - "0000000683", - "0000000694", - "0000000863", - "0000000866", - "0000000870", - "0000000880", - "0000000895", - "0000000935", - "0000000968", - "0000000970", - "0000000977", - "0000001015", - "0000001016", - "0000001060", - "0000001073", - "0000001082", - "0000001115", - "0000001119", - "0000001173", - "0000001195", - "0000001217", - "0000001248", - "0000001291", - "0000001297", - "0000001362", - "0000001405", - "0000001452", - "0000001493", - "0000001497", - "0000001506", - "0000001531", - "0000001591", - "0000001592", - "0000001635", - "0000001694", - "0000001779", - "0000001869", - "0000001946", - "0000001977", - "0000001979", - "0000002062", - "0000002091", - "0000002095", - "0000002257", - "0000002304", - "0000002397", - "0000002435", - "0000002442", - "0000002511", - "0000002513", - "0000002520", - "0000002534", - "0000002613", - "0000002619", - "0000002653", - "0000002704", - "0000002789", - "0000002795", - "0000002809", - "0000002812", - "0000002829", - "0000002847", - "0000002885", - "0000002914", - "0000002948", - "0000002978", - "0000002981", - "0000002983", - "0000003022", - "0000003029", - "0000003071", - "0000003125", - "0000003138", - "0000003148", - "0000003149", - "0000003182", - "0000003224", - "0000003239", - "0000003243", - "0000003256", - "0000003261", - "0000003273", - "0000003277", - "0000003303", - "0000003313", - "0000003316", - "0000003385", - "0000003415", - "0000003420", - "0000003428", - "0000003475", - "0000003525", - "0000003537", - "0000003541", - "0000003549", - "0000003577", - "0000003679", - "0000003682", - "0000003719", - "0000003721", - "0000003743", - "0000003782", - "0000003812", - "0000003814", - "0000003837", - "0000003848", - "0000003852", - "0000003859", - "0000003863", - "0000003907", - "0000003933", - "0000003938", - "0000004011", - "0000004046", - "0000004071", - "0000004082", - "0000004124", - "0000004130", - "0000004207", - "0000004212", - "0000004260", - "0000004286", - "0000004371", - "0000004396", - "0000004401", - "0000004404", - "0000004409", - "0000004445", - "0000004484", - "0000004550", - "0000004566", - "0000004590", - "0000004600", - "0000004627", - "0000004636", - "0000004642", - "0000004673", - "0000004688", - "0000004712", - "0000004739", - "0000004775", - "0000004815", - "0000004821", - "0000004864", - "0000004870", - "0000004889", - "0000004908", - "0000004912", - "0000004932", - "0000004948", - "0000004951", - "0000004976", - "0000005000", - "0000005016", - "0000005045", - "0000005048", - "0000005118", - "0000005162", - "0000005170", - "0000005186", - "0000005195", - "0000005202", - "0000005235", - "0000005239", - "0000005270", - "0000005294", - "0000005328", - "0000005355", - "0000005356", - "0000005376", - "0000005399", - "0000005416", - "0000005420", - "0000005436", - "0000005479", - "0000005492", - "0000005496", - "0000005536", - "0000005554", - "0000005568", - "0000005573", - "0000005582", - "0000005616", - "0000005682", - "0000005699", - "0000005764", - "0000005822", - "0000005823", - "0000005871", - "0000005897", - "0000005967", - "0000005971", - "0000006013", - "0000006025", - "0000006029", - "0000006030", - "0000006043", - "0000006063", - "0000006109", - "0000006128", - "0000006153", - "0000006158", - "0000006164", - "0000006205", - "0000006208", - "0000006238", - "0000006247", - "0000006299", - "0000006303", - "0000006350", - "0000006364", - "0000006404", - "0000006415", - "0000006423", - "0000006448", - "0000006486", - "0000006510", - "0000006514", - "0000006563", - "0000006593", - "0000006604", - "0000006612", - "0000006659", - "0000006702", - "0000006716", - "0000006728", - "0000006775", - "0000007002", - "0000007003", - "0000007030", - "0000007040", - "0000007128", - "0000007208", - "0000007264", - "0000007285", - "0000007295", - "0000007297", - "0000007302", - "0000007312", - "0000007373", - "0000007478", - "0000007517", - "0000007528", - "0000007535", - "0000007584", - "0000007596", - "0000007659", - "0000007684", - "0000007783", - "0000007798", - "0000007811", - "0000007819", - "0000007850", - "0000007864", - "0000007901", - "0000007974", - "0000007981", - "0000007987", - "0000007988", - "0000008000", - "0000008034", - "0000008071", - "0000008077", - "0000008102", - "0000008139", - "0000008175", - "0000008226", - "0000008258", - "0000008275", - "0000008289", - "0000008297", - "0000008305", - "0000008307", - "0000008373", - "0000008382", - "0000008411", - "0000008502", - "0000008534", - "0000008554", - "0000008584", - "0000008589", - "0000008590", - "0000008602", - "0000008656", - "0000008732", - "0000008756", - "0000008798", - "0000008815", - "0000008946", - "0000008955", - "0000008979", - "0000008998", - "0000009015", - "0000009031", - "0000009039", - "0000009071", - "0000009073", - "0000009075", - "0000009093", - "0000009102", - "0000009108", - "0000009141", - "0000009265", - "0000009311", - "0000009323", - "0000009351", - "0000009391", - "0000009437", - "0000009466", - "0000009469", - "0000009471", - "0000009543", - "0000009618", - "0000009669", - "0000009689", - "0000009759", - "0000009773", - "0000009832", - "0000009849", - "0000009917", - "0000009950" - ], - "n_documents": 347, - "field_usage": [ - { - "field_name": "consolidated_text", - "source_type": "unified", - "usage_type": "text", - "n_non_null": 347, - "n_total": 347, - "coverage": 1.0 - }, - { - "field_name": "order_to_delivery_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 333, - "n_total": 347, - "coverage": 0.9596541786743515 - }, - { - "field_name": "delivery_to_invoice_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 0, - "n_total": 347, - "coverage": 0.0 - }, - { - "field_name": "order_to_invoice_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 323, - "n_total": 347, - "coverage": 0.930835734870317 - }, - { - "field_name": "delay_from_requested_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 0, - "n_total": 347, - "coverage": 0.0 - } - ], - "row_counts": { - "total_documents": 10000, - "cluster_documents": 347 - }, - "sampling_warnings": [], - "reproducibility": { - "random_seed": 42, - "clustering_algorithm": "kmeans", - "embedding_model": "tfidf", - "n_clusters": 8, - "min_cluster_size": 5, - "delay_threshold_days": 7, - "analysis_timestamp": "2025-12-27T23:53:08.524827Z", - "package_version": "0.1.0", - "parameters": {} - }, - "source_files": [ - "../synthetic-data/sample_output/orders.json", - "../synthetic-data/sample_output/deliveries.json", - "../synthetic-data/sample_output/invoices.json", - "../synthetic-data/sample_output/doc_flows.json", - "../synthetic-data/sample_output/customers.json", - "../synthetic-data/sample_output/materials.json" - ], - "has_warnings": false, - "validation_issues": [ - "Low coverage (0%) for field delivery_to_invoice_days", - "Low coverage (0%) for field delay_from_requested_days" - ] - } - }, - { - "id": "PAT-7CF3DCD1", - "title": "Needs Friday / Customer Needs Friday / Friday", - "description": "Documents in this cluster frequently contain \"needs friday\", \"customer needs friday\", \"friday\". No statistically significant timing differences from baseline. Based on analysis of 360 documents.", - "top_phrases": [ - "needs friday", - "customer needs friday", - "friday", - "needs", - "customer needs", - "customer", - "expedite customer needs", - "hold customer needs", - "hold customer", - "expedite customer" - ], - "sample_snippets": [], - "occurrence": { - "count": 360, - "by_sales_org": { - "2000": 102, - "3000": 124, - "1000": 134 - }, - "by_customer_industry": { - "GOVERNMENT": 78, - "RETAIL": 103, - "INDUSTRIAL": 87, - "WHOLESALE": 92 - } - }, - "effect": {}, - "effects": [], - "confidence": "MEDIUM", - "confidence_score": 0.4, - "caveats": [ - "Observational analysis only; correlation does not imply causation.", - "Patterns based on text similarity; may not capture all relevant factors.", - "No statistically significant effects detected." - ], - "evidence": { - "doc_keys": [ - "0000000020", - "0000000022", - "0000000051", - "0000000075", - "0000000125", - "0000000152", - "0000000184", - "0000000194", - "0000000216", - "0000000234", - "0000000241", - "0000000267", - "0000000296", - "0000000358", - "0000000412", - "0000000413", - "0000000465", - "0000000483", - "0000000502", - "0000000540", - "0000000567", - "0000000598", - "0000000610", - "0000000638", - "0000000681", - "0000000700", - "0000000753", - "0000000812", - "0000000823", - "0000000860", - "0000000881", - "0000000883", - "0000000892", - "0000000896", - "0000000902", - "0000000906", - "0000000951", - "0000000955", - "0000000992", - "0000001021", - "0000001032", - "0000001034", - "0000001035", - "0000001056", - "0000001059", - "0000001072", - "0000001117", - "0000001170", - "0000001194", - "0000001200", - "0000001244", - "0000001254", - "0000001261", - "0000001347", - "0000001348", - "0000001419", - "0000001426", - "0000001456", - "0000001465", - "0000001488", - "0000001586", - "0000001610", - "0000001644", - "0000001651", - "0000001665", - "0000001670", - "0000001675", - "0000001678", - "0000001681", - "0000001720", - "0000001742", - "0000001752", - "0000001882", - "0000001903", - "0000001907", - "0000001909", - "0000001917", - "0000001918", - "0000001919", - "0000001926", - "0000001928", - "0000002010", - "0000002061", - "0000002103", - "0000002111", - "0000002117", - "0000002196", - "0000002247", - "0000002349", - "0000002412", - "0000002415", - "0000002500", - "0000002541", - "0000002587", - "0000002638", - "0000002662", - "0000002711", - "0000002755", - "0000002788", - "0000002804", - "0000002837", - "0000002840", - "0000002841", - "0000002846", - "0000002853", - "0000002901", - "0000002903", - "0000002919", - "0000002976", - "0000002986", - "0000003031", - "0000003056", - "0000003114", - "0000003145", - "0000003151", - "0000003153", - "0000003255", - "0000003263", - "0000003269", - "0000003272", - "0000003317", - "0000003321", - "0000003370", - "0000003395", - "0000003432", - "0000003457", - "0000003464", - "0000003482", - "0000003505", - "0000003519", - "0000003562", - "0000003574", - "0000003585", - "0000003587", - "0000003639", - "0000003680", - "0000003724", - "0000003748", - "0000003766", - "0000003839", - "0000003876", - "0000003893", - "0000003909", - "0000004053", - "0000004081", - "0000004104", - "0000004118", - "0000004122", - "0000004140", - "0000004165", - "0000004188", - "0000004242", - "0000004262", - "0000004288", - "0000004290", - "0000004307", - "0000004317", - "0000004345", - "0000004355", - "0000004360", - "0000004398", - "0000004413", - "0000004420", - "0000004434", - "0000004455", - "0000004488", - "0000004532", - "0000004541", - "0000004575", - "0000004616", - "0000004619", - "0000004635", - "0000004650", - "0000004676", - "0000004705", - "0000004711", - "0000004724", - "0000004730", - "0000004778", - "0000004832", - "0000004964", - "0000005002", - "0000005028", - "0000005040", - "0000005076", - "0000005081", - "0000005093", - "0000005109", - "0000005240", - "0000005246", - "0000005250", - "0000005338", - "0000005402", - "0000005407", - "0000005415", - "0000005452", - "0000005455", - "0000005457", - "0000005467", - "0000005484", - "0000005494", - "0000005512", - "0000005532", - "0000005549", - "0000005589", - "0000005632", - "0000005643", - "0000005651", - "0000005696", - "0000005719", - "0000005725", - "0000005800", - "0000005814", - "0000005827", - "0000005828", - "0000005848", - "0000005943", - "0000005964", - "0000005986", - "0000006106", - "0000006172", - "0000006209", - "0000006226", - "0000006279", - "0000006296", - "0000006425", - "0000006459", - "0000006463", - "0000006474", - "0000006487", - "0000006508", - "0000006521", - "0000006633", - "0000006680", - "0000006715", - "0000006761", - "0000006779", - "0000006826", - "0000006845", - "0000006884", - "0000006891", - "0000006898", - "0000006911", - "0000006912", - "0000006913", - "0000006935", - "0000006959", - "0000006965", - "0000006991", - "0000007005", - "0000007022", - "0000007046", - "0000007082", - "0000007099", - "0000007121", - "0000007155", - "0000007195", - "0000007197", - "0000007214", - "0000007250", - "0000007261", - "0000007283", - "0000007371", - "0000007402", - "0000007536", - "0000007575", - "0000007606", - "0000007609", - "0000007706", - "0000007734", - "0000007744", - "0000007827", - "0000007835", - "0000007843", - "0000007847", - "0000007870", - "0000007877", - "0000007894", - "0000007905", - "0000007911", - "0000007963", - "0000007973", - "0000008029", - "0000008103", - "0000008147", - "0000008153", - "0000008186", - "0000008223", - "0000008270", - "0000008272", - "0000008280", - "0000008321", - "0000008322", - "0000008327", - "0000008353", - "0000008402", - "0000008417", - "0000008424", - "0000008442", - "0000008479", - "0000008485", - "0000008494", - "0000008518", - "0000008524", - "0000008538", - "0000008550", - "0000008553", - "0000008560", - "0000008606", - "0000008609", - "0000008673", - "0000008681", - "0000008687", - "0000008718", - "0000008731", - "0000008750", - "0000008773", - "0000008799", - "0000008863", - "0000008872", - "0000008881", - "0000008886", - "0000008887", - "0000008888", - "0000008899", - "0000009016", - "0000009022", - "0000009072", - "0000009091", - "0000009130", - "0000009158", - "0000009220", - "0000009264", - "0000009320", - "0000009321", - "0000009338", - "0000009448", - "0000009481", - "0000009508", - "0000009531", - "0000009538", - "0000009542", - "0000009545", - "0000009563", - "0000009568", - "0000009571", - "0000009583", - "0000009706", - "0000009757", - "0000009789", - "0000009814", - "0000009815", - "0000009817", - "0000009834", - "0000009844", - "0000009887", - "0000009896", - "0000009912", - "0000009915", - "0000009977" - ], - "fields_used": [ - "consolidated_text", - "order_to_delivery_days", - "delivery_to_invoice_days", - "order_to_invoice_days", - "delay_from_requested_days" - ], - "sample_size": 360, - "total_population": 10000 - }, - "cluster_id": "1", - "created_at": "2025-12-27T23:53:08.530862Z", - "is_notable": false, - "full_evidence": { - "doc_keys": [ - "0000000020", - "0000000022", - "0000000051", - "0000000075", - "0000000125", - "0000000152", - "0000000184", - "0000000194", - "0000000216", - "0000000234", - "0000000241", - "0000000267", - "0000000296", - "0000000358", - "0000000412", - "0000000413", - "0000000465", - "0000000483", - "0000000502", - "0000000540", - "0000000567", - "0000000598", - "0000000610", - "0000000638", - "0000000681", - "0000000700", - "0000000753", - "0000000812", - "0000000823", - "0000000860", - "0000000881", - "0000000883", - "0000000892", - "0000000896", - "0000000902", - "0000000906", - "0000000951", - "0000000955", - "0000000992", - "0000001021", - "0000001032", - "0000001034", - "0000001035", - "0000001056", - "0000001059", - "0000001072", - "0000001117", - "0000001170", - "0000001194", - "0000001200", - "0000001244", - "0000001254", - "0000001261", - "0000001347", - "0000001348", - "0000001419", - "0000001426", - "0000001456", - "0000001465", - "0000001488", - "0000001586", - "0000001610", - "0000001644", - "0000001651", - "0000001665", - "0000001670", - "0000001675", - "0000001678", - "0000001681", - "0000001720", - "0000001742", - "0000001752", - "0000001882", - "0000001903", - "0000001907", - "0000001909", - "0000001917", - "0000001918", - "0000001919", - "0000001926", - "0000001928", - "0000002010", - "0000002061", - "0000002103", - "0000002111", - "0000002117", - "0000002196", - "0000002247", - "0000002349", - "0000002412", - "0000002415", - "0000002500", - "0000002541", - "0000002587", - "0000002638", - "0000002662", - "0000002711", - "0000002755", - "0000002788", - "0000002804", - "0000002837", - "0000002840", - "0000002841", - "0000002846", - "0000002853", - "0000002901", - "0000002903", - "0000002919", - "0000002976", - "0000002986", - "0000003031", - "0000003056", - "0000003114", - "0000003145", - "0000003151", - "0000003153", - "0000003255", - "0000003263", - "0000003269", - "0000003272", - "0000003317", - "0000003321", - "0000003370", - "0000003395", - "0000003432", - "0000003457", - "0000003464", - "0000003482", - "0000003505", - "0000003519", - "0000003562", - "0000003574", - "0000003585", - "0000003587", - "0000003639", - "0000003680", - "0000003724", - "0000003748", - "0000003766", - "0000003839", - "0000003876", - "0000003893", - "0000003909", - "0000004053", - "0000004081", - "0000004104", - "0000004118", - "0000004122", - "0000004140", - "0000004165", - "0000004188", - "0000004242", - "0000004262", - "0000004288", - "0000004290", - "0000004307", - "0000004317", - "0000004345", - "0000004355", - "0000004360", - "0000004398", - "0000004413", - "0000004420", - "0000004434", - "0000004455", - "0000004488", - "0000004532", - "0000004541", - "0000004575", - "0000004616", - "0000004619", - "0000004635", - "0000004650", - "0000004676", - "0000004705", - "0000004711", - "0000004724", - "0000004730", - "0000004778", - "0000004832", - "0000004964", - "0000005002", - "0000005028", - "0000005040", - "0000005076", - "0000005081", - "0000005093", - "0000005109", - "0000005240", - "0000005246", - "0000005250", - "0000005338", - "0000005402", - "0000005407", - "0000005415", - "0000005452", - "0000005455", - "0000005457", - "0000005467", - "0000005484", - "0000005494", - "0000005512", - "0000005532", - "0000005549", - "0000005589", - "0000005632", - "0000005643", - "0000005651", - "0000005696", - "0000005719", - "0000005725", - "0000005800", - "0000005814", - "0000005827", - "0000005828", - "0000005848", - "0000005943", - "0000005964", - "0000005986", - "0000006106", - "0000006172", - "0000006209", - "0000006226", - "0000006279", - "0000006296", - "0000006425", - "0000006459", - "0000006463", - "0000006474", - "0000006487", - "0000006508", - "0000006521", - "0000006633", - "0000006680", - "0000006715", - "0000006761", - "0000006779", - "0000006826", - "0000006845", - "0000006884", - "0000006891", - "0000006898", - "0000006911", - "0000006912", - "0000006913", - "0000006935", - "0000006959", - "0000006965", - "0000006991", - "0000007005", - "0000007022", - "0000007046", - "0000007082", - "0000007099", - "0000007121", - "0000007155", - "0000007195", - "0000007197", - "0000007214", - "0000007250", - "0000007261", - "0000007283", - "0000007371", - "0000007402", - "0000007536", - "0000007575", - "0000007606", - "0000007609", - "0000007706", - "0000007734", - "0000007744", - "0000007827", - "0000007835", - "0000007843", - "0000007847", - "0000007870", - "0000007877", - "0000007894", - "0000007905", - "0000007911", - "0000007963", - "0000007973", - "0000008029", - "0000008103", - "0000008147", - "0000008153", - "0000008186", - "0000008223", - "0000008270", - "0000008272", - "0000008280", - "0000008321", - "0000008322", - "0000008327", - "0000008353", - "0000008402", - "0000008417", - "0000008424", - "0000008442", - "0000008479", - "0000008485", - "0000008494", - "0000008518", - "0000008524", - "0000008538", - "0000008550", - "0000008553", - "0000008560", - "0000008606", - "0000008609", - "0000008673", - "0000008681", - "0000008687", - "0000008718", - "0000008731", - "0000008750", - "0000008773", - "0000008799", - "0000008863", - "0000008872", - "0000008881", - "0000008886", - "0000008887", - "0000008888", - "0000008899", - "0000009016", - "0000009022", - "0000009072", - "0000009091", - "0000009130", - "0000009158", - "0000009220", - "0000009264", - "0000009320", - "0000009321", - "0000009338", - "0000009448", - "0000009481", - "0000009508", - "0000009531", - "0000009538", - "0000009542", - "0000009545", - "0000009563", - "0000009568", - "0000009571", - "0000009583", - "0000009706", - "0000009757", - "0000009789", - "0000009814", - "0000009815", - "0000009817", - "0000009834", - "0000009844", - "0000009887", - "0000009896", - "0000009912", - "0000009915", - "0000009977" - ], - "n_documents": 360, - "field_usage": [ - { - "field_name": "consolidated_text", - "source_type": "unified", - "usage_type": "text", - "n_non_null": 360, - "n_total": 360, - "coverage": 1.0 - }, - { - "field_name": "order_to_delivery_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 347, - "n_total": 360, - "coverage": 0.9638888888888889 - }, - { - "field_name": "delivery_to_invoice_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 0, - "n_total": 360, - "coverage": 0.0 - }, - { - "field_name": "order_to_invoice_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 340, - "n_total": 360, - "coverage": 0.9444444444444444 - }, - { - "field_name": "delay_from_requested_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 0, - "n_total": 360, - "coverage": 0.0 - } - ], - "row_counts": { - "total_documents": 10000, - "cluster_documents": 360 - }, - "sampling_warnings": [], - "reproducibility": { - "random_seed": 42, - "clustering_algorithm": "kmeans", - "embedding_model": "tfidf", - "n_clusters": 8, - "min_cluster_size": 5, - "delay_threshold_days": 7, - "analysis_timestamp": "2025-12-27T23:53:08.530594Z", - "package_version": "0.1.0", - "parameters": {} - }, - "source_files": [ - "../synthetic-data/sample_output/orders.json", - "../synthetic-data/sample_output/deliveries.json", - "../synthetic-data/sample_output/invoices.json", - "../synthetic-data/sample_output/doc_flows.json", - "../synthetic-data/sample_output/customers.json", - "../synthetic-data/sample_output/materials.json" - ], - "has_warnings": false, - "validation_issues": [ - "Low coverage (0%) for field delivery_to_invoice_days", - "Low coverage (0%) for field delay_from_requested_days" - ] - } - }, - { - "id": "PAT-76CDCA00", - "title": "Hold / Credit / Credit Hold", - "description": "Documents in this cluster frequently contain \"hold\", \"credit\", \"credit hold\". No statistically significant timing differences from baseline. Based on analysis of 141 documents.", - "top_phrases": [ - "hold", - "credit", - "credit hold", - "hold expedite", - "hold credit", - "credit hold expedite", - "credit hold ref", - "hold ref", - "hold customer request", - "credit hold customer" - ], - "sample_snippets": [], - "occurrence": { - "count": 141, - "by_sales_org": { - "1000": 49, - "2000": 51, - "3000": 41 - }, - "by_customer_industry": { - "GOVERNMENT": 41, - "INDUSTRIAL": 34, - "RETAIL": 34, - "WHOLESALE": 32 - } - }, - "effect": {}, - "effects": [], - "confidence": "MEDIUM", - "confidence_score": 0.4, - "caveats": [ - "Observational analysis only; correlation does not imply causation.", - "Patterns based on text similarity; may not capture all relevant factors.", - "No statistically significant effects detected." - ], - "evidence": { - "doc_keys": [ - "0000000101", - "0000000281", - "0000000486", - "0000000604", - "0000000847", - "0000000927", - "0000000931", - "0000000952", - "0000001068", - "0000001125", - "0000001138", - "0000001165", - "0000001199", - "0000001230", - "0000001322", - "0000001378", - "0000001396", - "0000001443", - "0000001447", - "0000001462", - "0000001525", - "0000001597", - "0000001831", - "0000001856", - "0000001860", - "0000001930", - "0000001952", - "0000001956", - "0000001962", - "0000001966", - "0000001980", - "0000002063", - "0000002102", - "0000002421", - "0000002502", - "0000002524", - "0000002533", - "0000002629", - "0000002715", - "0000002726", - "0000002728", - "0000002793", - "0000002820", - "0000002848", - "0000002932", - "0000003003", - "0000003010", - "0000003052", - "0000003064", - "0000003123", - "0000003176", - "0000003225", - "0000003234", - "0000003250", - "0000003352", - "0000003449", - "0000003460", - "0000003649", - "0000003753", - "0000003770", - "0000003857", - "0000003905", - "0000003926", - "0000004229", - "0000004269", - "0000004342", - "0000004346", - "0000004397", - "0000004443", - "0000004464", - "0000004476", - "0000004527", - "0000004587", - "0000004647", - "0000004862", - "0000005106", - "0000005122", - "0000005184", - "0000005244", - "0000005269", - "0000005332", - "0000005350", - "0000005447", - "0000005518", - "0000005556", - "0000005562", - "0000005570", - "0000005619", - "0000005668", - "0000005908", - "0000005929", - "0000005956", - "0000005980", - "0000006140", - "0000006198", - "0000006473", - "0000006540", - "0000006576", - "0000006592", - "0000006630", - "0000006691", - "0000006722", - "0000006744", - "0000006852", - "0000006960", - "0000007165", - "0000007170", - "0000007202", - "0000007267", - "0000007347", - "0000007377", - "0000007482", - "0000007513", - "0000007522", - "0000007579", - "0000007687", - "0000007719", - "0000007902", - "0000008010", - "0000008044", - "0000008116", - "0000008125", - "0000008211", - "0000008419", - "0000008420", - "0000008434", - "0000008452", - "0000008688", - "0000008793", - "0000008934", - "0000009242", - "0000009245", - "0000009249", - "0000009283", - "0000009319", - "0000009334", - "0000009445", - "0000009524", - "0000009588", - "0000009593", - "0000009663" - ], - "fields_used": [ - "consolidated_text", - "order_to_delivery_days", - "delivery_to_invoice_days", - "order_to_invoice_days", - "delay_from_requested_days" - ], - "sample_size": 141, - "total_population": 10000 - }, - "cluster_id": "2", - "created_at": "2025-12-27T23:53:08.534607Z", - "is_notable": false, - "full_evidence": { - "doc_keys": [ - "0000000101", - "0000000281", - "0000000486", - "0000000604", - "0000000847", - "0000000927", - "0000000931", - "0000000952", - "0000001068", - "0000001125", - "0000001138", - "0000001165", - "0000001199", - "0000001230", - "0000001322", - "0000001378", - "0000001396", - "0000001443", - "0000001447", - "0000001462", - "0000001525", - "0000001597", - "0000001831", - "0000001856", - "0000001860", - "0000001930", - "0000001952", - "0000001956", - "0000001962", - "0000001966", - "0000001980", - "0000002063", - "0000002102", - "0000002421", - "0000002502", - "0000002524", - "0000002533", - "0000002629", - "0000002715", - "0000002726", - "0000002728", - "0000002793", - "0000002820", - "0000002848", - "0000002932", - "0000003003", - "0000003010", - "0000003052", - "0000003064", - "0000003123", - "0000003176", - "0000003225", - "0000003234", - "0000003250", - "0000003352", - "0000003449", - "0000003460", - "0000003649", - "0000003753", - "0000003770", - "0000003857", - "0000003905", - "0000003926", - "0000004229", - "0000004269", - "0000004342", - "0000004346", - "0000004397", - "0000004443", - "0000004464", - "0000004476", - "0000004527", - "0000004587", - "0000004647", - "0000004862", - "0000005106", - "0000005122", - "0000005184", - "0000005244", - "0000005269", - "0000005332", - "0000005350", - "0000005447", - "0000005518", - "0000005556", - "0000005562", - "0000005570", - "0000005619", - "0000005668", - "0000005908", - "0000005929", - "0000005956", - "0000005980", - "0000006140", - "0000006198", - "0000006473", - "0000006540", - "0000006576", - "0000006592", - "0000006630", - "0000006691", - "0000006722", - "0000006744", - "0000006852", - "0000006960", - "0000007165", - "0000007170", - "0000007202", - "0000007267", - "0000007347", - "0000007377", - "0000007482", - "0000007513", - "0000007522", - "0000007579", - "0000007687", - "0000007719", - "0000007902", - "0000008010", - "0000008044", - "0000008116", - "0000008125", - "0000008211", - "0000008419", - "0000008420", - "0000008434", - "0000008452", - "0000008688", - "0000008793", - "0000008934", - "0000009242", - "0000009245", - "0000009249", - "0000009283", - "0000009319", - "0000009334", - "0000009445", - "0000009524", - "0000009588", - "0000009593", - "0000009663" - ], - "n_documents": 141, - "field_usage": [ - { - "field_name": "consolidated_text", - "source_type": "unified", - "usage_type": "text", - "n_non_null": 141, - "n_total": 141, - "coverage": 1.0 - }, - { - "field_name": "order_to_delivery_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 138, - "n_total": 141, - "coverage": 0.9787234042553191 - }, - { - "field_name": "delivery_to_invoice_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 0, - "n_total": 141, - "coverage": 0.0 - }, - { - "field_name": "order_to_invoice_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 133, - "n_total": 141, - "coverage": 0.9432624113475178 - }, - { - "field_name": "delay_from_requested_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 0, - "n_total": 141, - "coverage": 0.0 - } - ], - "row_counts": { - "total_documents": 10000, - "cluster_documents": 141 - }, - "sampling_warnings": [], - "reproducibility": { - "random_seed": 42, - "clustering_algorithm": "kmeans", - "embedding_model": "tfidf", - "n_clusters": 8, - "min_cluster_size": 5, - "delay_threshold_days": 7, - "analysis_timestamp": "2025-12-27T23:53:08.534528Z", - "package_version": "0.1.0", - "parameters": {} - }, - "source_files": [ - "../synthetic-data/sample_output/orders.json", - "../synthetic-data/sample_output/deliveries.json", - "../synthetic-data/sample_output/invoices.json", - "../synthetic-data/sample_output/doc_flows.json", - "../synthetic-data/sample_output/customers.json", - "../synthetic-data/sample_output/materials.json" - ], - "has_warnings": false, - "validation_issues": [ - "Low coverage (0%) for field delivery_to_invoice_days", - "Low coverage (0%) for field delay_from_requested_days" - ] - } - }, - { - "id": "PAT-CF84D0A6", - "title": "Rush / Order / Backorder", - "description": "Documents in this cluster frequently contain \"rush\", \"order\", \"backorder\". No statistically significant timing differences from baseline. Based on analysis of 819 documents.", - "top_phrases": [ - "rush", - "order", - "backorder", - "01", - "03", - "exped", - "stock", - "expedited", - "urgent", - "09" - ], - "sample_snippets": [], - "occurrence": { - "count": 819, - "by_sales_org": { - "3000": 282, - "1000": 234, - "2000": 303 - }, - "by_customer_industry": { - "GOVERNMENT": 173, - "INDUSTRIAL": 196, - "RETAIL": 238, - "WHOLESALE": 212 - } - }, - "effect": {}, - "effects": [], - "confidence": "MEDIUM", - "confidence_score": 0.4, - "caveats": [ - "Observational analysis only; correlation does not imply causation.", - "Patterns based on text similarity; may not capture all relevant factors.", - "No statistically significant effects detected." - ], - "evidence": { - "doc_keys": [ - "0000000023", - "0000000028", - "0000000055", - "0000000063", - "0000000070", - "0000000084", - "0000000091", - "0000000096", - "0000000105", - "0000000111", - "0000000121", - "0000000151", - "0000000187", - "0000000206", - "0000000231", - "0000000232", - "0000000237", - "0000000240", - "0000000248", - "0000000265", - "0000000271", - "0000000282", - "0000000322", - "0000000326", - "0000000384", - "0000000390", - "0000000399", - "0000000400", - "0000000408", - "0000000436", - "0000000438", - "0000000445", - "0000000453", - "0000000454", - "0000000461", - "0000000467", - "0000000481", - "0000000496", - "0000000526", - "0000000527", - "0000000529", - "0000000541", - "0000000553", - "0000000554", - "0000000559", - "0000000574", - "0000000576", - "0000000580", - "0000000617", - "0000000624", - "0000000651", - "0000000659", - "0000000670", - "0000000688", - "0000000696", - "0000000706", - "0000000723", - "0000000736", - "0000000737", - "0000000745", - "0000000757", - "0000000761", - "0000000792", - "0000000811", - "0000000859", - "0000000886", - "0000000887", - "0000000905", - "0000000917", - "0000000924", - "0000000954", - "0000000997", - "0000001017", - "0000001038", - "0000001041", - "0000001043", - "0000001046", - "0000001058", - "0000001062", - "0000001067", - "0000001074", - "0000001079", - "0000001087", - "0000001118", - "0000001133", - "0000001158", - "0000001159", - "0000001197", - "0000001220", - "0000001226", - "0000001236", - "0000001237", - "0000001247", - "0000001287", - "0000001302", - "0000001306", - "0000001319", - "0000001325", - "0000001335", - "0000001350", - "0000001379", - "0000001394", - "0000001407", - "0000001423", - "0000001432", - "0000001433", - "0000001440", - "0000001489", - "0000001491", - "0000001496", - "0000001502", - "0000001509", - "0000001512", - "0000001513", - "0000001518", - "0000001544", - "0000001566", - "0000001578", - "0000001588", - "0000001603", - "0000001624", - "0000001633", - "0000001636", - "0000001639", - "0000001643", - "0000001648", - "0000001657", - "0000001660", - "0000001686", - "0000001689", - "0000001706", - "0000001714", - "0000001736", - "0000001751", - "0000001767", - "0000001789", - "0000001801", - "0000001806", - "0000001837", - "0000001843", - "0000001854", - "0000001866", - "0000001867", - "0000001885", - "0000001887", - "0000001895", - "0000001904", - "0000001912", - "0000001921", - "0000001940", - "0000001941", - "0000001942", - "0000001964", - "0000001971", - "0000001976", - "0000001985", - "0000002018", - "0000002036", - "0000002037", - "0000002039", - "0000002048", - "0000002072", - "0000002079", - "0000002084", - "0000002130", - "0000002150", - "0000002154", - "0000002184", - "0000002191", - "0000002215", - "0000002236", - "0000002240", - "0000002249", - "0000002253", - "0000002256", - "0000002269", - "0000002277", - "0000002289", - "0000002299", - "0000002316", - "0000002320", - "0000002326", - "0000002327", - "0000002329", - "0000002330", - "0000002339", - "0000002340", - "0000002345", - "0000002362", - "0000002395", - "0000002403", - "0000002419", - "0000002428", - "0000002446", - "0000002447", - "0000002455", - "0000002458", - "0000002463", - "0000002497", - "0000002510", - "0000002512", - "0000002529", - "0000002538", - "0000002544", - "0000002557", - "0000002579", - "0000002593", - "0000002604", - "0000002624", - "0000002646", - "0000002660", - "0000002668", - "0000002671", - "0000002687", - "0000002701", - "0000002707", - "0000002719", - "0000002729", - "0000002744", - "0000002761", - "0000002768", - "0000002784", - "0000002785", - "0000002796", - "0000002834", - "0000002835", - "0000002836", - "0000002845", - "0000002868", - "0000002869", - "0000002877", - "0000002880", - "0000002899", - "0000002907", - "0000002912", - "0000002934", - "0000002937", - "0000002956", - "0000002971", - "0000002977", - "0000002987", - "0000002991", - "0000003014", - "0000003019", - "0000003026", - "0000003040", - "0000003044", - "0000003047", - "0000003081", - "0000003090", - "0000003092", - "0000003100", - "0000003105", - "0000003135", - "0000003143", - "0000003179", - "0000003186", - "0000003208", - "0000003217", - "0000003223", - "0000003226", - "0000003241", - "0000003285", - "0000003291", - "0000003293", - "0000003330", - "0000003368", - "0000003372", - "0000003405", - "0000003421", - "0000003436", - "0000003448", - "0000003473", - "0000003495", - "0000003516", - "0000003517", - "0000003551", - "0000003555", - "0000003558", - "0000003568", - "0000003576", - "0000003581", - "0000003594", - "0000003606", - "0000003615", - "0000003618", - "0000003622", - "0000003637", - "0000003670", - "0000003676", - "0000003702", - "0000003713", - "0000003718", - "0000003732", - "0000003763", - "0000003774", - "0000003784", - "0000003789", - "0000003795", - "0000003813", - "0000003815", - "0000003819", - "0000003826", - "0000003835", - "0000003877", - "0000003886", - "0000003888", - "0000003906", - "0000003929", - "0000003946", - "0000003971", - "0000003972", - "0000003977", - "0000003978", - "0000003980", - "0000004015", - "0000004024", - "0000004025", - "0000004031", - "0000004052", - "0000004054", - "0000004058", - "0000004062", - "0000004085", - "0000004108", - "0000004114", - "0000004117", - "0000004137", - "0000004148", - "0000004151", - "0000004155", - "0000004168", - "0000004173", - "0000004213", - "0000004228", - "0000004230", - "0000004232", - "0000004261", - "0000004278", - "0000004282", - "0000004289", - "0000004299", - "0000004319", - "0000004330", - "0000004331", - "0000004334", - "0000004341", - "0000004356", - "0000004359", - "0000004369", - "0000004411", - "0000004421", - "0000004422", - "0000004423", - "0000004461", - "0000004471", - "0000004520", - "0000004522", - "0000004530", - "0000004540", - "0000004545", - "0000004557", - "0000004603", - "0000004615", - "0000004637", - "0000004648", - "0000004652", - "0000004704", - "0000004706", - "0000004707", - "0000004726", - "0000004733", - "0000004746", - "0000004782", - "0000004783", - "0000004800", - "0000004805", - "0000004835", - "0000004851", - "0000004881", - "0000004899", - "0000004903", - "0000004926", - "0000004943", - "0000004958", - "0000004971", - "0000004973", - "0000004980", - "0000004981", - "0000004982", - "0000004990", - "0000005032", - "0000005037", - "0000005042", - "0000005044", - "0000005047", - "0000005049", - "0000005057", - "0000005067", - "0000005134", - "0000005147", - "0000005148", - "0000005155", - "0000005159", - "0000005160", - "0000005165", - "0000005178", - "0000005179", - "0000005206", - "0000005218", - "0000005236", - "0000005238", - "0000005249", - "0000005252", - "0000005257", - "0000005287", - "0000005292", - "0000005304", - "0000005305", - "0000005311", - "0000005335", - "0000005336", - "0000005340", - "0000005352", - "0000005353", - "0000005385", - "0000005390", - "0000005400", - "0000005408", - "0000005422", - "0000005477", - "0000005482", - "0000005483", - "0000005488", - "0000005500", - "0000005544", - "0000005545", - "0000005546", - "0000005566", - "0000005572", - "0000005574", - "0000005594", - "0000005609", - "0000005629", - "0000005639", - "0000005675", - "0000005683", - "0000005706", - "0000005742", - "0000005746", - "0000005749", - "0000005762", - "0000005769", - "0000005811", - "0000005835", - "0000005846", - "0000005853", - "0000005856", - "0000005860", - "0000005865", - "0000005913", - "0000005914", - "0000005934", - "0000005953", - "0000006004", - "0000006010", - "0000006011", - "0000006032", - "0000006047", - "0000006056", - "0000006059", - "0000006061", - "0000006084", - "0000006119", - "0000006133", - "0000006169", - "0000006176", - "0000006190", - "0000006207", - "0000006229", - "0000006237", - "0000006239", - "0000006283", - "0000006306", - "0000006316", - "0000006356", - "0000006371", - "0000006381", - "0000006385", - "0000006389", - "0000006401", - "0000006412", - "0000006413", - "0000006418", - "0000006426", - "0000006443", - "0000006453", - "0000006464", - "0000006475", - "0000006498", - "0000006535", - "0000006537", - "0000006538", - "0000006542", - "0000006557", - "0000006582", - "0000006595", - "0000006615", - "0000006616", - "0000006634", - "0000006638", - "0000006645", - "0000006684", - "0000006689", - "0000006693", - "0000006720", - "0000006721", - "0000006755", - "0000006757", - "0000006759", - "0000006760", - "0000006765", - "0000006767", - "0000006781", - "0000006790", - "0000006806", - "0000006810", - "0000006820", - "0000006823", - "0000006834", - "0000006878", - "0000006896", - "0000006900", - "0000006903", - "0000006915", - "0000006919", - "0000006934", - "0000006958", - "0000006966", - "0000006985", - "0000007023", - "0000007043", - "0000007051", - "0000007058", - "0000007071", - "0000007079", - "0000007083", - "0000007084", - "0000007102", - "0000007106", - "0000007118", - "0000007120", - "0000007138", - "0000007141", - "0000007152", - "0000007161", - "0000007162", - "0000007175", - "0000007177", - "0000007181", - "0000007183", - "0000007184", - "0000007186", - "0000007187", - "0000007199", - "0000007222", - "0000007228", - "0000007260", - "0000007272", - "0000007274", - "0000007288", - "0000007313", - "0000007333", - "0000007353", - "0000007360", - "0000007361", - "0000007362", - "0000007363", - "0000007372", - "0000007375", - "0000007383", - "0000007390", - "0000007400", - "0000007403", - "0000007405", - "0000007410", - "0000007421", - "0000007455", - "0000007462", - "0000007463", - "0000007466", - "0000007473", - "0000007480", - "0000007491", - "0000007504", - "0000007506", - "0000007507", - "0000007520", - "0000007533", - "0000007558", - "0000007577", - "0000007601", - "0000007619", - "0000007628", - "0000007641", - "0000007656", - "0000007661", - "0000007671", - "0000007730", - "0000007735", - "0000007743", - "0000007754", - "0000007760", - "0000007761", - "0000007766", - "0000007768", - "0000007779", - "0000007789", - "0000007790", - "0000007793", - "0000007804", - "0000007830", - "0000007838", - "0000007841", - "0000007849", - "0000007874", - "0000007880", - "0000007898", - "0000007904", - "0000007915", - "0000007917", - "0000007920", - "0000007939", - "0000007955", - "0000007958", - "0000007967", - "0000007993", - "0000007995", - "0000007996", - "0000007997", - "0000008004", - "0000008008", - "0000008025", - "0000008036", - "0000008048", - "0000008062", - "0000008069", - "0000008081", - "0000008094", - "0000008097", - "0000008109", - "0000008122", - "0000008124", - "0000008134", - "0000008135", - "0000008140", - "0000008181", - "0000008184", - "0000008191", - "0000008213", - "0000008219", - "0000008234", - "0000008241", - "0000008243", - "0000008247", - "0000008254", - "0000008269", - "0000008271", - "0000008273", - "0000008279", - "0000008281", - "0000008283", - "0000008284", - "0000008301", - "0000008312", - "0000008319", - "0000008328", - "0000008340", - "0000008374", - "0000008376", - "0000008387", - "0000008390", - "0000008413", - "0000008416", - "0000008425", - "0000008430", - "0000008435", - "0000008437", - "0000008490", - "0000008569", - "0000008572", - "0000008577", - "0000008601", - "0000008607", - "0000008649", - "0000008651", - "0000008652", - "0000008665", - "0000008691", - "0000008698", - "0000008700", - "0000008711", - "0000008715", - "0000008717", - "0000008738", - "0000008739", - "0000008744", - "0000008747", - "0000008764", - "0000008777", - "0000008791", - "0000008805", - "0000008810", - "0000008821", - "0000008825", - "0000008867", - "0000008874", - "0000008885", - "0000008900", - "0000008912", - "0000008931", - "0000008932", - "0000008940", - "0000008943", - "0000008957", - "0000008961", - "0000008963", - "0000008976", - "0000008983", - "0000008993", - "0000008999", - "0000009042", - "0000009080", - "0000009085", - "0000009098", - "0000009099", - "0000009119", - "0000009127", - "0000009137", - "0000009146", - "0000009164", - "0000009171", - "0000009182", - "0000009185", - "0000009192", - "0000009212", - "0000009251", - "0000009261", - "0000009278", - "0000009299", - "0000009304", - "0000009313", - "0000009315", - "0000009318", - "0000009325", - "0000009344", - "0000009349", - "0000009379", - "0000009387", - "0000009389", - "0000009393", - "0000009399", - "0000009401", - "0000009424", - "0000009432", - "0000009446", - "0000009462", - "0000009489", - "0000009490", - "0000009499", - "0000009509", - "0000009523", - "0000009532", - "0000009541", - "0000009544", - "0000009552", - "0000009557", - "0000009592", - "0000009594", - "0000009631", - "0000009632", - "0000009639", - "0000009643", - "0000009644", - "0000009650", - "0000009666", - "0000009677", - "0000009678", - "0000009680", - "0000009690", - "0000009697", - "0000009708", - "0000009726", - "0000009727", - "0000009735", - "0000009751", - "0000009755", - "0000009769", - "0000009777", - "0000009778", - "0000009795", - "0000009805", - "0000009808", - "0000009838", - "0000009842", - "0000009857", - "0000009858", - "0000009860", - "0000009873", - "0000009876", - "0000009880", - "0000009898", - "0000009903", - "0000009908", - "0000009923", - "0000009979", - "0000009980", - "0000009981", - "0000009991" - ], - "fields_used": [ - "consolidated_text", - "order_to_delivery_days", - "delivery_to_invoice_days", - "order_to_invoice_days", - "delay_from_requested_days" - ], - "sample_size": 819, - "total_population": 10000 - }, - "cluster_id": "3", - "created_at": "2025-12-27T23:53:08.548170Z", - "is_notable": false, - "full_evidence": { - "doc_keys": [ - "0000000023", - "0000000028", - "0000000055", - "0000000063", - "0000000070", - "0000000084", - "0000000091", - "0000000096", - "0000000105", - "0000000111", - "0000000121", - "0000000151", - "0000000187", - "0000000206", - "0000000231", - "0000000232", - "0000000237", - "0000000240", - "0000000248", - "0000000265", - "0000000271", - "0000000282", - "0000000322", - "0000000326", - "0000000384", - "0000000390", - "0000000399", - "0000000400", - "0000000408", - "0000000436", - "0000000438", - "0000000445", - "0000000453", - "0000000454", - "0000000461", - "0000000467", - "0000000481", - "0000000496", - "0000000526", - "0000000527", - "0000000529", - "0000000541", - "0000000553", - "0000000554", - "0000000559", - "0000000574", - "0000000576", - "0000000580", - "0000000617", - "0000000624", - "0000000651", - "0000000659", - "0000000670", - "0000000688", - "0000000696", - "0000000706", - "0000000723", - "0000000736", - "0000000737", - "0000000745", - "0000000757", - "0000000761", - "0000000792", - "0000000811", - "0000000859", - "0000000886", - "0000000887", - "0000000905", - "0000000917", - "0000000924", - "0000000954", - "0000000997", - "0000001017", - "0000001038", - "0000001041", - "0000001043", - "0000001046", - "0000001058", - "0000001062", - "0000001067", - "0000001074", - "0000001079", - "0000001087", - "0000001118", - "0000001133", - "0000001158", - "0000001159", - "0000001197", - "0000001220", - "0000001226", - "0000001236", - "0000001237", - "0000001247", - "0000001287", - "0000001302", - "0000001306", - "0000001319", - "0000001325", - "0000001335", - "0000001350", - "0000001379", - "0000001394", - "0000001407", - "0000001423", - "0000001432", - "0000001433", - "0000001440", - "0000001489", - "0000001491", - "0000001496", - "0000001502", - "0000001509", - "0000001512", - "0000001513", - "0000001518", - "0000001544", - "0000001566", - "0000001578", - "0000001588", - "0000001603", - "0000001624", - "0000001633", - "0000001636", - "0000001639", - "0000001643", - "0000001648", - "0000001657", - "0000001660", - "0000001686", - "0000001689", - "0000001706", - "0000001714", - "0000001736", - "0000001751", - "0000001767", - "0000001789", - "0000001801", - "0000001806", - "0000001837", - "0000001843", - "0000001854", - "0000001866", - "0000001867", - "0000001885", - "0000001887", - "0000001895", - "0000001904", - "0000001912", - "0000001921", - "0000001940", - "0000001941", - "0000001942", - "0000001964", - "0000001971", - "0000001976", - "0000001985", - "0000002018", - "0000002036", - "0000002037", - "0000002039", - "0000002048", - "0000002072", - "0000002079", - "0000002084", - "0000002130", - "0000002150", - "0000002154", - "0000002184", - "0000002191", - "0000002215", - "0000002236", - "0000002240", - "0000002249", - "0000002253", - "0000002256", - "0000002269", - "0000002277", - "0000002289", - "0000002299", - "0000002316", - "0000002320", - "0000002326", - "0000002327", - "0000002329", - "0000002330", - "0000002339", - "0000002340", - "0000002345", - "0000002362", - "0000002395", - "0000002403", - "0000002419", - "0000002428", - "0000002446", - "0000002447", - "0000002455", - "0000002458", - "0000002463", - "0000002497", - "0000002510", - "0000002512", - "0000002529", - "0000002538", - "0000002544", - "0000002557", - "0000002579", - "0000002593", - "0000002604", - "0000002624", - "0000002646", - "0000002660", - "0000002668", - "0000002671", - "0000002687", - "0000002701", - "0000002707", - "0000002719", - "0000002729", - "0000002744", - "0000002761", - "0000002768", - "0000002784", - "0000002785", - "0000002796", - "0000002834", - "0000002835", - "0000002836", - "0000002845", - "0000002868", - "0000002869", - "0000002877", - "0000002880", - "0000002899", - "0000002907", - "0000002912", - "0000002934", - "0000002937", - "0000002956", - "0000002971", - "0000002977", - "0000002987", - "0000002991", - "0000003014", - "0000003019", - "0000003026", - "0000003040", - "0000003044", - "0000003047", - "0000003081", - "0000003090", - "0000003092", - "0000003100", - "0000003105", - "0000003135", - "0000003143", - "0000003179", - "0000003186", - "0000003208", - "0000003217", - "0000003223", - "0000003226", - "0000003241", - "0000003285", - "0000003291", - "0000003293", - "0000003330", - "0000003368", - "0000003372", - "0000003405", - "0000003421", - "0000003436", - "0000003448", - "0000003473", - "0000003495", - "0000003516", - "0000003517", - "0000003551", - "0000003555", - "0000003558", - "0000003568", - "0000003576", - "0000003581", - "0000003594", - "0000003606", - "0000003615", - "0000003618", - "0000003622", - "0000003637", - "0000003670", - "0000003676", - "0000003702", - "0000003713", - "0000003718", - "0000003732", - "0000003763", - "0000003774", - "0000003784", - "0000003789", - "0000003795", - "0000003813", - "0000003815", - "0000003819", - "0000003826", - "0000003835", - "0000003877", - "0000003886", - "0000003888", - "0000003906", - "0000003929", - "0000003946", - "0000003971", - "0000003972", - "0000003977", - "0000003978", - "0000003980", - "0000004015", - "0000004024", - "0000004025", - "0000004031", - "0000004052", - "0000004054", - "0000004058", - "0000004062", - "0000004085", - "0000004108", - "0000004114", - "0000004117", - "0000004137", - "0000004148", - "0000004151", - "0000004155", - "0000004168", - "0000004173", - "0000004213", - "0000004228", - "0000004230", - "0000004232", - "0000004261", - "0000004278", - "0000004282", - "0000004289", - "0000004299", - "0000004319", - "0000004330", - "0000004331", - "0000004334", - "0000004341", - "0000004356", - "0000004359", - "0000004369", - "0000004411", - "0000004421", - "0000004422", - "0000004423", - "0000004461", - "0000004471", - "0000004520", - "0000004522", - "0000004530", - "0000004540", - "0000004545", - "0000004557", - "0000004603", - "0000004615", - "0000004637", - "0000004648", - "0000004652", - "0000004704", - "0000004706", - "0000004707", - "0000004726", - "0000004733", - "0000004746", - "0000004782", - "0000004783", - "0000004800", - "0000004805", - "0000004835", - "0000004851", - "0000004881", - "0000004899", - "0000004903", - "0000004926", - "0000004943", - "0000004958", - "0000004971", - "0000004973", - "0000004980", - "0000004981", - "0000004982", - "0000004990", - "0000005032", - "0000005037", - "0000005042", - "0000005044", - "0000005047", - "0000005049", - "0000005057", - "0000005067", - "0000005134", - "0000005147", - "0000005148", - "0000005155", - "0000005159", - "0000005160", - "0000005165", - "0000005178", - "0000005179", - "0000005206", - "0000005218", - "0000005236", - "0000005238", - "0000005249", - "0000005252", - "0000005257", - "0000005287", - "0000005292", - "0000005304", - "0000005305", - "0000005311", - "0000005335", - "0000005336", - "0000005340", - "0000005352", - "0000005353", - "0000005385", - "0000005390", - "0000005400", - "0000005408", - "0000005422", - "0000005477", - "0000005482", - "0000005483", - "0000005488", - "0000005500", - "0000005544", - "0000005545", - "0000005546", - "0000005566", - "0000005572", - "0000005574", - "0000005594", - "0000005609", - "0000005629", - "0000005639", - "0000005675", - "0000005683", - "0000005706", - "0000005742", - "0000005746", - "0000005749", - "0000005762", - "0000005769", - "0000005811", - "0000005835", - "0000005846", - "0000005853", - "0000005856", - "0000005860", - "0000005865", - "0000005913", - "0000005914", - "0000005934", - "0000005953", - "0000006004", - "0000006010", - "0000006011", - "0000006032", - "0000006047", - "0000006056", - "0000006059", - "0000006061", - "0000006084", - "0000006119", - "0000006133", - "0000006169", - "0000006176", - "0000006190", - "0000006207", - "0000006229", - "0000006237", - "0000006239", - "0000006283", - "0000006306", - "0000006316", - "0000006356", - "0000006371", - "0000006381", - "0000006385", - "0000006389", - "0000006401", - "0000006412", - "0000006413", - "0000006418", - "0000006426", - "0000006443", - "0000006453", - "0000006464", - "0000006475", - "0000006498", - "0000006535", - "0000006537", - "0000006538", - "0000006542", - "0000006557", - "0000006582", - "0000006595", - "0000006615", - "0000006616", - "0000006634", - "0000006638", - "0000006645", - "0000006684", - "0000006689", - "0000006693", - "0000006720", - "0000006721", - "0000006755", - "0000006757", - "0000006759", - "0000006760", - "0000006765", - "0000006767", - "0000006781", - "0000006790", - "0000006806", - "0000006810", - "0000006820", - "0000006823", - "0000006834", - "0000006878", - "0000006896", - "0000006900", - "0000006903", - "0000006915", - "0000006919", - "0000006934", - "0000006958", - "0000006966", - "0000006985", - "0000007023", - "0000007043", - "0000007051", - "0000007058", - "0000007071", - "0000007079", - "0000007083", - "0000007084", - "0000007102", - "0000007106", - "0000007118", - "0000007120", - "0000007138", - "0000007141", - "0000007152", - "0000007161", - "0000007162", - "0000007175", - "0000007177", - "0000007181", - "0000007183", - "0000007184", - "0000007186", - "0000007187", - "0000007199", - "0000007222", - "0000007228", - "0000007260", - "0000007272", - "0000007274", - "0000007288", - "0000007313", - "0000007333", - "0000007353", - "0000007360", - "0000007361", - "0000007362", - "0000007363", - "0000007372", - "0000007375", - "0000007383", - "0000007390", - "0000007400", - "0000007403", - "0000007405", - "0000007410", - "0000007421", - "0000007455", - "0000007462", - "0000007463", - "0000007466", - "0000007473", - "0000007480", - "0000007491", - "0000007504", - "0000007506", - "0000007507", - "0000007520", - "0000007533", - "0000007558", - "0000007577", - "0000007601", - "0000007619", - "0000007628", - "0000007641", - "0000007656", - "0000007661", - "0000007671", - "0000007730", - "0000007735", - "0000007743", - "0000007754", - "0000007760", - "0000007761", - "0000007766", - "0000007768", - "0000007779", - "0000007789", - "0000007790", - "0000007793", - "0000007804", - "0000007830", - "0000007838", - "0000007841", - "0000007849", - "0000007874", - "0000007880", - "0000007898", - "0000007904", - "0000007915", - "0000007917", - "0000007920", - "0000007939", - "0000007955", - "0000007958", - "0000007967", - "0000007993", - "0000007995", - "0000007996", - "0000007997", - "0000008004", - "0000008008", - "0000008025", - "0000008036", - "0000008048", - "0000008062", - "0000008069", - "0000008081", - "0000008094", - "0000008097", - "0000008109", - "0000008122", - "0000008124", - "0000008134", - "0000008135", - "0000008140", - "0000008181", - "0000008184", - "0000008191", - "0000008213", - "0000008219", - "0000008234", - "0000008241", - "0000008243", - "0000008247", - "0000008254", - "0000008269", - "0000008271", - "0000008273", - "0000008279", - "0000008281", - "0000008283", - "0000008284", - "0000008301", - "0000008312", - "0000008319", - "0000008328", - "0000008340", - "0000008374", - "0000008376", - "0000008387", - "0000008390", - "0000008413", - "0000008416", - "0000008425", - "0000008430", - "0000008435", - "0000008437", - "0000008490", - "0000008569", - "0000008572", - "0000008577", - "0000008601", - "0000008607", - "0000008649", - "0000008651", - "0000008652", - "0000008665", - "0000008691", - "0000008698", - "0000008700", - "0000008711", - "0000008715", - "0000008717", - "0000008738", - "0000008739", - "0000008744", - "0000008747", - "0000008764", - "0000008777", - "0000008791", - "0000008805", - "0000008810", - "0000008821", - "0000008825", - "0000008867", - "0000008874", - "0000008885", - "0000008900", - "0000008912", - "0000008931", - "0000008932", - "0000008940", - "0000008943", - "0000008957", - "0000008961", - "0000008963", - "0000008976", - "0000008983", - "0000008993", - "0000008999", - "0000009042", - "0000009080", - "0000009085", - "0000009098", - "0000009099", - "0000009119", - "0000009127", - "0000009137", - "0000009146", - "0000009164", - "0000009171", - "0000009182", - "0000009185", - "0000009192", - "0000009212", - "0000009251", - "0000009261", - "0000009278", - "0000009299", - "0000009304", - "0000009313", - "0000009315", - "0000009318", - "0000009325", - "0000009344", - "0000009349", - "0000009379", - "0000009387", - "0000009389", - "0000009393", - "0000009399", - "0000009401", - "0000009424", - "0000009432", - "0000009446", - "0000009462", - "0000009489", - "0000009490", - "0000009499", - "0000009509", - "0000009523", - "0000009532", - "0000009541", - "0000009544", - "0000009552", - "0000009557", - "0000009592", - "0000009594", - "0000009631", - "0000009632", - "0000009639", - "0000009643", - "0000009644", - "0000009650", - "0000009666", - "0000009677", - "0000009678", - "0000009680", - "0000009690", - "0000009697", - "0000009708", - "0000009726", - "0000009727", - "0000009735", - "0000009751", - "0000009755", - "0000009769", - "0000009777", - "0000009778", - "0000009795", - "0000009805", - "0000009808", - "0000009838", - "0000009842", - "0000009857", - "0000009858", - "0000009860", - "0000009873", - "0000009876", - "0000009880", - "0000009898", - "0000009903", - "0000009908", - "0000009923", - "0000009979", - "0000009980", - "0000009981", - "0000009991" - ], - "n_documents": 819, - "field_usage": [ - { - "field_name": "consolidated_text", - "source_type": "unified", - "usage_type": "text", - "n_non_null": 819, - "n_total": 819, - "coverage": 1.0 - }, - { - "field_name": "order_to_delivery_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 791, - "n_total": 819, - "coverage": 0.9658119658119658 - }, - { - "field_name": "delivery_to_invoice_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 0, - "n_total": 819, - "coverage": 0.0 - }, - { - "field_name": "order_to_invoice_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 759, - "n_total": 819, - "coverage": 0.9267399267399268 - }, - { - "field_name": "delay_from_requested_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 0, - "n_total": 819, - "coverage": 0.0 - } - ], - "row_counts": { - "total_documents": 10000, - "cluster_documents": 819 - }, - "sampling_warnings": [], - "reproducibility": { - "random_seed": 42, - "clustering_algorithm": "kmeans", - "embedding_model": "tfidf", - "n_clusters": 8, - "min_cluster_size": 5, - "delay_threshold_days": 7, - "analysis_timestamp": "2025-12-27T23:53:08.547803Z", - "package_version": "0.1.0", - "parameters": {} - }, - "source_files": [ - "../synthetic-data/sample_output/orders.json", - "../synthetic-data/sample_output/deliveries.json", - "../synthetic-data/sample_output/invoices.json", - "../synthetic-data/sample_output/doc_flows.json", - "../synthetic-data/sample_output/customers.json", - "../synthetic-data/sample_output/materials.json" - ], - "has_warnings": false, - "validation_issues": [ - "Low coverage (0%) for field delivery_to_invoice_days", - "Low coverage (0%) for field delay_from_requested_days" - ] - } - }, - { - "id": "PAT-43D46B4A", - "title": "Expedite / Expedite Ref / Expedite Expedite", - "description": "Documents in this cluster frequently contain \"expedite\", \"expedite ref\", \"expedite expedite\". No statistically significant timing differences from baseline. Based on analysis of 402 documents.", - "top_phrases": [ - "expedite", - "expedite ref", - "expedite expedite", - "order expedite", - "discount expedite", - "ref", - "stock expedite", - "order", - "discount", - "backorder expedite" - ], - "sample_snippets": [], - "occurrence": { - "count": 402, - "by_sales_org": { - "1000": 117, - "3000": 128, - "2000": 157 - }, - "by_customer_industry": { - "WHOLESALE": 107, - "INDUSTRIAL": 110, - "RETAIL": 88, - "GOVERNMENT": 97 - } - }, - "effect": {}, - "effects": [], - "confidence": "MEDIUM", - "confidence_score": 0.4, - "caveats": [ - "Observational analysis only; correlation does not imply causation.", - "Patterns based on text similarity; may not capture all relevant factors.", - "No statistically significant effects detected." - ], - "evidence": { - "doc_keys": [ - "0000000007", - "0000000019", - "0000000031", - "0000000041", - "0000000078", - "0000000099", - "0000000124", - "0000000138", - "0000000139", - "0000000183", - "0000000186", - "0000000254", - "0000000262", - "0000000284", - "0000000313", - "0000000352", - "0000000363", - "0000000368", - "0000000420", - "0000000446", - "0000000491", - "0000000545", - "0000000552", - "0000000568", - "0000000591", - "0000000632", - "0000000698", - "0000000715", - "0000000731", - "0000000744", - "0000000771", - "0000000776", - "0000000851", - "0000000930", - "0000000964", - "0000000967", - "0000000969", - "0000000994", - "0000001022", - "0000001027", - "0000001116", - "0000001224", - "0000001298", - "0000001304", - "0000001309", - "0000001352", - "0000001374", - "0000001376", - "0000001382", - "0000001422", - "0000001500", - "0000001607", - "0000001684", - "0000001707", - "0000001725", - "0000001726", - "0000001732", - "0000001739", - "0000001744", - "0000001797", - "0000001803", - "0000001805", - "0000001820", - "0000001861", - "0000001873", - "0000001929", - "0000001954", - "0000001994", - "0000001995", - "0000002007", - "0000002011", - "0000002024", - "0000002044", - "0000002077", - "0000002083", - "0000002099", - "0000002137", - "0000002138", - "0000002140", - "0000002147", - "0000002186", - "0000002206", - "0000002238", - "0000002263", - "0000002273", - "0000002334", - "0000002378", - "0000002386", - "0000002398", - "0000002407", - "0000002420", - "0000002429", - "0000002432", - "0000002437", - "0000002475", - "0000002537", - "0000002561", - "0000002569", - "0000002594", - "0000002610", - "0000002611", - "0000002627", - "0000002633", - "0000002634", - "0000002706", - "0000002717", - "0000002732", - "0000002734", - "0000002791", - "0000002855", - "0000002916", - "0000002917", - "0000002920", - "0000002921", - "0000002941", - "0000002969", - "0000003004", - "0000003009", - "0000003033", - "0000003036", - "0000003045", - "0000003053", - "0000003104", - "0000003110", - "0000003112", - "0000003121", - "0000003139", - "0000003174", - "0000003289", - "0000003314", - "0000003345", - "0000003360", - "0000003371", - "0000003381", - "0000003459", - "0000003509", - "0000003510", - "0000003564", - "0000003590", - "0000003591", - "0000003642", - "0000003664", - "0000003666", - "0000003712", - "0000003739", - "0000003777", - "0000003798", - "0000003807", - "0000003821", - "0000003831", - "0000003845", - "0000003847", - "0000003873", - "0000003913", - "0000003917", - "0000003925", - "0000003935", - "0000003955", - "0000004020", - "0000004050", - "0000004080", - "0000004088", - "0000004115", - "0000004136", - "0000004180", - "0000004186", - "0000004218", - "0000004253", - "0000004349", - "0000004419", - "0000004429", - "0000004442", - "0000004472", - "0000004533", - "0000004543", - "0000004629", - "0000004664", - "0000004684", - "0000004686", - "0000004697", - "0000004719", - "0000004720", - "0000004784", - "0000004785", - "0000004824", - "0000004833", - "0000004861", - "0000004930", - "0000004978", - "0000005025", - "0000005029", - "0000005039", - "0000005055", - "0000005060", - "0000005089", - "0000005091", - "0000005126", - "0000005137", - "0000005142", - "0000005200", - "0000005220", - "0000005222", - "0000005274", - "0000005283", - "0000005288", - "0000005342", - "0000005359", - "0000005360", - "0000005393", - "0000005446", - "0000005465", - "0000005469", - "0000005508", - "0000005586", - "0000005596", - "0000005613", - "0000005624", - "0000005630", - "0000005649", - "0000005654", - "0000005692", - "0000005723", - "0000005728", - "0000005759", - "0000005766", - "0000005775", - "0000005779", - "0000005808", - "0000005809", - "0000005810", - "0000005831", - "0000005842", - "0000005857", - "0000005954", - "0000005960", - "0000005969", - "0000005992", - "0000006038", - "0000006041", - "0000006077", - "0000006089", - "0000006101", - "0000006122", - "0000006151", - "0000006152", - "0000006183", - "0000006187", - "0000006213", - "0000006251", - "0000006255", - "0000006286", - "0000006352", - "0000006360", - "0000006376", - "0000006386", - "0000006429", - "0000006431", - "0000006451", - "0000006452", - "0000006494", - "0000006502", - "0000006527", - "0000006591", - "0000006613", - "0000006622", - "0000006624", - "0000006640", - "0000006675", - "0000006735", - "0000006747", - "0000006799", - "0000006838", - "0000006866", - "0000006868", - "0000006881", - "0000006918", - "0000006994", - "0000006996", - "0000007047", - "0000007052", - "0000007055", - "0000007077", - "0000007092", - "0000007097", - "0000007126", - "0000007192", - "0000007196", - "0000007220", - "0000007223", - "0000007268", - "0000007293", - "0000007315", - "0000007317", - "0000007321", - "0000007331", - "0000007355", - "0000007369", - "0000007392", - "0000007412", - "0000007427", - "0000007454", - "0000007485", - "0000007509", - "0000007512", - "0000007527", - "0000007552", - "0000007557", - "0000007566", - "0000007573", - "0000007576", - "0000007581", - "0000007598", - "0000007607", - "0000007646", - "0000007652", - "0000007683", - "0000007691", - "0000007693", - "0000007698", - "0000007712", - "0000007753", - "0000007797", - "0000007807", - "0000007820", - "0000007857", - "0000007879", - "0000007890", - "0000007937", - "0000007971", - "0000008001", - "0000008002", - "0000008130", - "0000008151", - "0000008174", - "0000008188", - "0000008195", - "0000008264", - "0000008303", - "0000008377", - "0000008441", - "0000008516", - "0000008522", - "0000008540", - "0000008541", - "0000008579", - "0000008592", - "0000008655", - "0000008703", - "0000008707", - "0000008716", - "0000008746", - "0000008826", - "0000008846", - "0000008896", - "0000008902", - "0000008907", - "0000008929", - "0000008933", - "0000008952", - "0000009037", - "0000009065", - "0000009067", - "0000009077", - "0000009092", - "0000009135", - "0000009154", - "0000009169", - "0000009225", - "0000009226", - "0000009237", - "0000009254", - "0000009277", - "0000009330", - "0000009332", - "0000009337", - "0000009352", - "0000009360", - "0000009378", - "0000009381", - "0000009390", - "0000009422", - "0000009427", - "0000009428", - "0000009498", - "0000009512", - "0000009534", - "0000009599", - "0000009607", - "0000009642", - "0000009719", - "0000009728", - "0000009774", - "0000009788", - "0000009790", - "0000009793", - "0000009807", - "0000009848", - "0000009853", - "0000009855", - "0000009867", - "0000009929", - "0000009995" - ], - "fields_used": [ - "consolidated_text", - "order_to_delivery_days", - "delivery_to_invoice_days", - "order_to_invoice_days", - "delay_from_requested_days" - ], - "sample_size": 402, - "total_population": 10000 - }, - "cluster_id": "4", - "created_at": "2025-12-27T23:53:08.552820Z", - "is_notable": false, - "full_evidence": { - "doc_keys": [ - "0000000007", - "0000000019", - "0000000031", - "0000000041", - "0000000078", - "0000000099", - "0000000124", - "0000000138", - "0000000139", - "0000000183", - "0000000186", - "0000000254", - "0000000262", - "0000000284", - "0000000313", - "0000000352", - "0000000363", - "0000000368", - "0000000420", - "0000000446", - "0000000491", - "0000000545", - "0000000552", - "0000000568", - "0000000591", - "0000000632", - "0000000698", - "0000000715", - "0000000731", - "0000000744", - "0000000771", - "0000000776", - "0000000851", - "0000000930", - "0000000964", - "0000000967", - "0000000969", - "0000000994", - "0000001022", - "0000001027", - "0000001116", - "0000001224", - "0000001298", - "0000001304", - "0000001309", - "0000001352", - "0000001374", - "0000001376", - "0000001382", - "0000001422", - "0000001500", - "0000001607", - "0000001684", - "0000001707", - "0000001725", - "0000001726", - "0000001732", - "0000001739", - "0000001744", - "0000001797", - "0000001803", - "0000001805", - "0000001820", - "0000001861", - "0000001873", - "0000001929", - "0000001954", - "0000001994", - "0000001995", - "0000002007", - "0000002011", - "0000002024", - "0000002044", - "0000002077", - "0000002083", - "0000002099", - "0000002137", - "0000002138", - "0000002140", - "0000002147", - "0000002186", - "0000002206", - "0000002238", - "0000002263", - "0000002273", - "0000002334", - "0000002378", - "0000002386", - "0000002398", - "0000002407", - "0000002420", - "0000002429", - "0000002432", - "0000002437", - "0000002475", - "0000002537", - "0000002561", - "0000002569", - "0000002594", - "0000002610", - "0000002611", - "0000002627", - "0000002633", - "0000002634", - "0000002706", - "0000002717", - "0000002732", - "0000002734", - "0000002791", - "0000002855", - "0000002916", - "0000002917", - "0000002920", - "0000002921", - "0000002941", - "0000002969", - "0000003004", - "0000003009", - "0000003033", - "0000003036", - "0000003045", - "0000003053", - "0000003104", - "0000003110", - "0000003112", - "0000003121", - "0000003139", - "0000003174", - "0000003289", - "0000003314", - "0000003345", - "0000003360", - "0000003371", - "0000003381", - "0000003459", - "0000003509", - "0000003510", - "0000003564", - "0000003590", - "0000003591", - "0000003642", - "0000003664", - "0000003666", - "0000003712", - "0000003739", - "0000003777", - "0000003798", - "0000003807", - "0000003821", - "0000003831", - "0000003845", - "0000003847", - "0000003873", - "0000003913", - "0000003917", - "0000003925", - "0000003935", - "0000003955", - "0000004020", - "0000004050", - "0000004080", - "0000004088", - "0000004115", - "0000004136", - "0000004180", - "0000004186", - "0000004218", - "0000004253", - "0000004349", - "0000004419", - "0000004429", - "0000004442", - "0000004472", - "0000004533", - "0000004543", - "0000004629", - "0000004664", - "0000004684", - "0000004686", - "0000004697", - "0000004719", - "0000004720", - "0000004784", - "0000004785", - "0000004824", - "0000004833", - "0000004861", - "0000004930", - "0000004978", - "0000005025", - "0000005029", - "0000005039", - "0000005055", - "0000005060", - "0000005089", - "0000005091", - "0000005126", - "0000005137", - "0000005142", - "0000005200", - "0000005220", - "0000005222", - "0000005274", - "0000005283", - "0000005288", - "0000005342", - "0000005359", - "0000005360", - "0000005393", - "0000005446", - "0000005465", - "0000005469", - "0000005508", - "0000005586", - "0000005596", - "0000005613", - "0000005624", - "0000005630", - "0000005649", - "0000005654", - "0000005692", - "0000005723", - "0000005728", - "0000005759", - "0000005766", - "0000005775", - "0000005779", - "0000005808", - "0000005809", - "0000005810", - "0000005831", - "0000005842", - "0000005857", - "0000005954", - "0000005960", - "0000005969", - "0000005992", - "0000006038", - "0000006041", - "0000006077", - "0000006089", - "0000006101", - "0000006122", - "0000006151", - "0000006152", - "0000006183", - "0000006187", - "0000006213", - "0000006251", - "0000006255", - "0000006286", - "0000006352", - "0000006360", - "0000006376", - "0000006386", - "0000006429", - "0000006431", - "0000006451", - "0000006452", - "0000006494", - "0000006502", - "0000006527", - "0000006591", - "0000006613", - "0000006622", - "0000006624", - "0000006640", - "0000006675", - "0000006735", - "0000006747", - "0000006799", - "0000006838", - "0000006866", - "0000006868", - "0000006881", - "0000006918", - "0000006994", - "0000006996", - "0000007047", - "0000007052", - "0000007055", - "0000007077", - "0000007092", - "0000007097", - "0000007126", - "0000007192", - "0000007196", - "0000007220", - "0000007223", - "0000007268", - "0000007293", - "0000007315", - "0000007317", - "0000007321", - "0000007331", - "0000007355", - "0000007369", - "0000007392", - "0000007412", - "0000007427", - "0000007454", - "0000007485", - "0000007509", - "0000007512", - "0000007527", - "0000007552", - "0000007557", - "0000007566", - "0000007573", - "0000007576", - "0000007581", - "0000007598", - "0000007607", - "0000007646", - "0000007652", - "0000007683", - "0000007691", - "0000007693", - "0000007698", - "0000007712", - "0000007753", - "0000007797", - "0000007807", - "0000007820", - "0000007857", - "0000007879", - "0000007890", - "0000007937", - "0000007971", - "0000008001", - "0000008002", - "0000008130", - "0000008151", - "0000008174", - "0000008188", - "0000008195", - "0000008264", - "0000008303", - "0000008377", - "0000008441", - "0000008516", - "0000008522", - "0000008540", - "0000008541", - "0000008579", - "0000008592", - "0000008655", - "0000008703", - "0000008707", - "0000008716", - "0000008746", - "0000008826", - "0000008846", - "0000008896", - "0000008902", - "0000008907", - "0000008929", - "0000008933", - "0000008952", - "0000009037", - "0000009065", - "0000009067", - "0000009077", - "0000009092", - "0000009135", - "0000009154", - "0000009169", - "0000009225", - "0000009226", - "0000009237", - "0000009254", - "0000009277", - "0000009330", - "0000009332", - "0000009337", - "0000009352", - "0000009360", - "0000009378", - "0000009381", - "0000009390", - "0000009422", - "0000009427", - "0000009428", - "0000009498", - "0000009512", - "0000009534", - "0000009599", - "0000009607", - "0000009642", - "0000009719", - "0000009728", - "0000009774", - "0000009788", - "0000009790", - "0000009793", - "0000009807", - "0000009848", - "0000009853", - "0000009855", - "0000009867", - "0000009929", - "0000009995" - ], - "n_documents": 402, - "field_usage": [ - { - "field_name": "consolidated_text", - "source_type": "unified", - "usage_type": "text", - "n_non_null": 402, - "n_total": 402, - "coverage": 1.0 - }, - { - "field_name": "order_to_delivery_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 390, - "n_total": 402, - "coverage": 0.9701492537313433 - }, - { - "field_name": "delivery_to_invoice_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 0, - "n_total": 402, - "coverage": 0.0 - }, - { - "field_name": "order_to_invoice_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 375, - "n_total": 402, - "coverage": 0.9328358208955224 - }, - { - "field_name": "delay_from_requested_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 0, - "n_total": 402, - "coverage": 0.0 - } - ], - "row_counts": { - "total_documents": 10000, - "cluster_documents": 402 - }, - "sampling_warnings": [], - "reproducibility": { - "random_seed": 42, - "clustering_algorithm": "kmeans", - "embedding_model": "tfidf", - "n_clusters": 8, - "min_cluster_size": 5, - "delay_threshold_days": 7, - "analysis_timestamp": "2025-12-27T23:53:08.552691Z", - "package_version": "0.1.0", - "parameters": {} - }, - "source_files": [ - "../synthetic-data/sample_output/orders.json", - "../synthetic-data/sample_output/deliveries.json", - "../synthetic-data/sample_output/invoices.json", - "../synthetic-data/sample_output/doc_flows.json", - "../synthetic-data/sample_output/customers.json", - "../synthetic-data/sample_output/materials.json" - ], - "has_warnings": false, - "validation_issues": [ - "Low coverage (0%) for field delivery_to_invoice_days", - "Low coverage (0%) for field delay_from_requested_days" - ] - } - }, - { - "id": "PAT-4DC2ADD9", - "title": "Partial / Ship / Partial Ship", - "description": "Documents in this cluster frequently contain \"partial\", \"ship\", \"partial ship\". No statistically significant timing differences from baseline. Based on analysis of 195 documents.", - "top_phrases": [ - "partial", - "ship", - "partial ship", - "shipment ok", - "ok", - "shipment", - "partial shipment ok", - "partial shipment", - "ship partial", - "ref" - ], - "sample_snippets": [], - "occurrence": { - "count": 195, - "by_sales_org": { - "2000": 70, - "1000": 54, - "3000": 71 - }, - "by_customer_industry": { - "WHOLESALE": 50, - "RETAIL": 53, - "GOVERNMENT": 39, - "INDUSTRIAL": 53 - } - }, - "effect": {}, - "effects": [], - "confidence": "MEDIUM", - "confidence_score": 0.4, - "caveats": [ - "Observational analysis only; correlation does not imply causation.", - "Patterns based on text similarity; may not capture all relevant factors.", - "No statistically significant effects detected." - ], - "evidence": { - "doc_keys": [ - "0000000018", - "0000000067", - "0000000123", - "0000000130", - "0000000182", - "0000000223", - "0000000258", - "0000000288", - "0000000321", - "0000000337", - "0000000351", - "0000000361", - "0000000476", - "0000000495", - "0000000497", - "0000000511", - "0000000600", - "0000000609", - "0000000640", - "0000000645", - "0000000658", - "0000000742", - "0000000780", - "0000000904", - "0000000914", - "0000001006", - "0000001024", - "0000001100", - "0000001301", - "0000001311", - "0000001371", - "0000001386", - "0000001551", - "0000001564", - "0000001569", - "0000001575", - "0000001649", - "0000001685", - "0000001727", - "0000001733", - "0000001740", - "0000001846", - "0000001908", - "0000001945", - "0000001981", - "0000002023", - "0000002105", - "0000002118", - "0000002172", - "0000002176", - "0000002201", - "0000002250", - "0000002298", - "0000002372", - "0000002478", - "0000002509", - "0000002643", - "0000002663", - "0000002740", - "0000002759", - "0000002790", - "0000002908", - "0000002910", - "0000002958", - "0000002997", - "0000003080", - "0000003133", - "0000003185", - "0000003193", - "0000003215", - "0000003245", - "0000003299", - "0000003325", - "0000003408", - "0000003451", - "0000003462", - "0000003707", - "0000003708", - "0000003720", - "0000003744", - "0000003749", - "0000003768", - "0000003772", - "0000003781", - "0000003810", - "0000003911", - "0000003965", - "0000004153", - "0000004183", - "0000004265", - "0000004295", - "0000004368", - "0000004499", - "0000004528", - "0000004657", - "0000004658", - "0000004682", - "0000004786", - "0000004812", - "0000004836", - "0000004929", - "0000004953", - "0000004985", - "0000005064", - "0000005201", - "0000005215", - "0000005255", - "0000005329", - "0000005379", - "0000005384", - "0000005388", - "0000005438", - "0000005487", - "0000005497", - "0000005601", - "0000005795", - "0000005850", - "0000005911", - "0000005932", - "0000005937", - "0000005984", - "0000006092", - "0000006100", - "0000006201", - "0000006334", - "0000006342", - "0000006367", - "0000006397", - "0000006433", - "0000006504", - "0000006669", - "0000006777", - "0000006873", - "0000006883", - "0000007142", - "0000007235", - "0000007244", - "0000007256", - "0000007310", - "0000007339", - "0000007378", - "0000007387", - "0000007396", - "0000007444", - "0000007453", - "0000007502", - "0000007531", - "0000007541", - "0000007635", - "0000007685", - "0000007748", - "0000007806", - "0000007812", - "0000007832", - "0000007848", - "0000007869", - "0000007924", - "0000008035", - "0000008059", - "0000008101", - "0000008185", - "0000008343", - "0000008467", - "0000008491", - "0000008585", - "0000008629", - "0000008690", - "0000008742", - "0000008781", - "0000008833", - "0000008837", - "0000008843", - "0000008928", - "0000008966", - "0000009012", - "0000009084", - "0000009096", - "0000009230", - "0000009240", - "0000009415", - "0000009423", - "0000009442", - "0000009468", - "0000009601", - "0000009611", - "0000009612", - "0000009662", - "0000009671", - "0000009703", - "0000009763", - "0000009792", - "0000009830", - "0000009871", - "0000009893", - "0000009922" - ], - "fields_used": [ - "consolidated_text", - "order_to_delivery_days", - "delivery_to_invoice_days", - "order_to_invoice_days", - "delay_from_requested_days" - ], - "sample_size": 195, - "total_population": 10000 - }, - "cluster_id": "5", - "created_at": "2025-12-27T23:53:08.556731Z", - "is_notable": false, - "full_evidence": { - "doc_keys": [ - "0000000018", - "0000000067", - "0000000123", - "0000000130", - "0000000182", - "0000000223", - "0000000258", - "0000000288", - "0000000321", - "0000000337", - "0000000351", - "0000000361", - "0000000476", - "0000000495", - "0000000497", - "0000000511", - "0000000600", - "0000000609", - "0000000640", - "0000000645", - "0000000658", - "0000000742", - "0000000780", - "0000000904", - "0000000914", - "0000001006", - "0000001024", - "0000001100", - "0000001301", - "0000001311", - "0000001371", - "0000001386", - "0000001551", - "0000001564", - "0000001569", - "0000001575", - "0000001649", - "0000001685", - "0000001727", - "0000001733", - "0000001740", - "0000001846", - "0000001908", - "0000001945", - "0000001981", - "0000002023", - "0000002105", - "0000002118", - "0000002172", - "0000002176", - "0000002201", - "0000002250", - "0000002298", - "0000002372", - "0000002478", - "0000002509", - "0000002643", - "0000002663", - "0000002740", - "0000002759", - "0000002790", - "0000002908", - "0000002910", - "0000002958", - "0000002997", - "0000003080", - "0000003133", - "0000003185", - "0000003193", - "0000003215", - "0000003245", - "0000003299", - "0000003325", - "0000003408", - "0000003451", - "0000003462", - "0000003707", - "0000003708", - "0000003720", - "0000003744", - "0000003749", - "0000003768", - "0000003772", - "0000003781", - "0000003810", - "0000003911", - "0000003965", - "0000004153", - "0000004183", - "0000004265", - "0000004295", - "0000004368", - "0000004499", - "0000004528", - "0000004657", - "0000004658", - "0000004682", - "0000004786", - "0000004812", - "0000004836", - "0000004929", - "0000004953", - "0000004985", - "0000005064", - "0000005201", - "0000005215", - "0000005255", - "0000005329", - "0000005379", - "0000005384", - "0000005388", - "0000005438", - "0000005487", - "0000005497", - "0000005601", - "0000005795", - "0000005850", - "0000005911", - "0000005932", - "0000005937", - "0000005984", - "0000006092", - "0000006100", - "0000006201", - "0000006334", - "0000006342", - "0000006367", - "0000006397", - "0000006433", - "0000006504", - "0000006669", - "0000006777", - "0000006873", - "0000006883", - "0000007142", - "0000007235", - "0000007244", - "0000007256", - "0000007310", - "0000007339", - "0000007378", - "0000007387", - "0000007396", - "0000007444", - "0000007453", - "0000007502", - "0000007531", - "0000007541", - "0000007635", - "0000007685", - "0000007748", - "0000007806", - "0000007812", - "0000007832", - "0000007848", - "0000007869", - "0000007924", - "0000008035", - "0000008059", - "0000008101", - "0000008185", - "0000008343", - "0000008467", - "0000008491", - "0000008585", - "0000008629", - "0000008690", - "0000008742", - "0000008781", - "0000008833", - "0000008837", - "0000008843", - "0000008928", - "0000008966", - "0000009012", - "0000009084", - "0000009096", - "0000009230", - "0000009240", - "0000009415", - "0000009423", - "0000009442", - "0000009468", - "0000009601", - "0000009611", - "0000009612", - "0000009662", - "0000009671", - "0000009703", - "0000009763", - "0000009792", - "0000009830", - "0000009871", - "0000009893", - "0000009922" - ], - "n_documents": 195, - "field_usage": [ - { - "field_name": "consolidated_text", - "source_type": "unified", - "usage_type": "text", - "n_non_null": 195, - "n_total": 195, - "coverage": 1.0 - }, - { - "field_name": "order_to_delivery_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 179, - "n_total": 195, - "coverage": 0.9179487179487179 - }, - { - "field_name": "delivery_to_invoice_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 0, - "n_total": 195, - "coverage": 0.0 - }, - { - "field_name": "order_to_invoice_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 176, - "n_total": 195, - "coverage": 0.9025641025641026 - }, - { - "field_name": "delay_from_requested_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 0, - "n_total": 195, - "coverage": 0.0 - } - ], - "row_counts": { - "total_documents": 10000, - "cluster_documents": 195 - }, - "sampling_warnings": [], - "reproducibility": { - "random_seed": 42, - "clustering_algorithm": "kmeans", - "embedding_model": "tfidf", - "n_clusters": 8, - "min_cluster_size": 5, - "delay_threshold_days": 7, - "analysis_timestamp": "2025-12-27T23:53:08.556665Z", - "package_version": "0.1.0", - "parameters": {} - }, - "source_files": [ - "../synthetic-data/sample_output/orders.json", - "../synthetic-data/sample_output/deliveries.json", - "../synthetic-data/sample_output/invoices.json", - "../synthetic-data/sample_output/doc_flows.json", - "../synthetic-data/sample_output/customers.json", - "../synthetic-data/sample_output/materials.json" - ], - "has_warnings": false, - "validation_issues": [ - "Low coverage (0%) for field delivery_to_invoice_days", - "Low coverage (0%) for field delay_from_requested_days" - ] - } - }, - { - "id": "PAT-8BB0F9C7", - "title": "Request / Customer Request / Customer", - "description": "Documents in this cluster frequently contain \"request\", \"customer request\", \"customer\". No statistically significant timing differences from baseline. Based on analysis of 361 documents.", - "top_phrases": [ - "request", - "customer request", - "customer", - "expedite customer request", - "expedite customer", - "expedite", - "rush customer request", - "order customer request", - "partial customer request", - "partial customer" - ], - "sample_snippets": [], - "occurrence": { - "count": 361, - "by_sales_org": { - "2000": 125, - "3000": 123, - "1000": 113 - }, - "by_customer_industry": { - "WHOLESALE": 87, - "GOVERNMENT": 98, - "INDUSTRIAL": 85, - "RETAIL": 91 - } - }, - "effect": {}, - "effects": [], - "confidence": "MEDIUM", - "confidence_score": 0.4, - "caveats": [ - "Observational analysis only; correlation does not imply causation.", - "Patterns based on text similarity; may not capture all relevant factors.", - "No statistically significant effects detected." - ], - "evidence": { - "doc_keys": [ - "0000000100", - "0000000112", - "0000000148", - "0000000163", - "0000000219", - "0000000246", - "0000000253", - "0000000331", - "0000000367", - "0000000427", - "0000000439", - "0000000503", - "0000000572", - "0000000595", - "0000000599", - "0000000642", - "0000000643", - "0000000676", - "0000000702", - "0000000730", - "0000000809", - "0000000831", - "0000000842", - "0000000852", - "0000000889", - "0000000933", - "0000000947", - "0000000980", - "0000001002", - "0000001023", - "0000001077", - "0000001137", - "0000001157", - "0000001186", - "0000001228", - "0000001260", - "0000001272", - "0000001288", - "0000001299", - "0000001361", - "0000001411", - "0000001451", - "0000001454", - "0000001472", - "0000001486", - "0000001533", - "0000001553", - "0000001560", - "0000001601", - "0000001605", - "0000001613", - "0000001645", - "0000001650", - "0000001745", - "0000001787", - "0000001857", - "0000001876", - "0000001896", - "0000001898", - "0000001932", - "0000001933", - "0000002008", - "0000002151", - "0000002165", - "0000002182", - "0000002192", - "0000002217", - "0000002282", - "0000002286", - "0000002306", - "0000002324", - "0000002467", - "0000002521", - "0000002553", - "0000002566", - "0000002581", - "0000002583", - "0000002588", - "0000002666", - "0000002696", - "0000002703", - "0000002733", - "0000002826", - "0000002863", - "0000002876", - "0000002890", - "0000002904", - "0000002953", - "0000003048", - "0000003067", - "0000003086", - "0000003132", - "0000003161", - "0000003165", - "0000003204", - "0000003319", - "0000003362", - "0000003393", - "0000003419", - "0000003430", - "0000003446", - "0000003453", - "0000003469", - "0000003483", - "0000003488", - "0000003504", - "0000003514", - "0000003515", - "0000003552", - "0000003557", - "0000003567", - "0000003613", - "0000003614", - "0000003617", - "0000003650", - "0000003660", - "0000003668", - "0000003686", - "0000003706", - "0000003823", - "0000003830", - "0000003849", - "0000003858", - "0000003868", - "0000003890", - "0000003912", - "0000003931", - "0000003957", - "0000003979", - "0000004000", - "0000004003", - "0000004008", - "0000004023", - "0000004051", - "0000004057", - "0000004070", - "0000004075", - "0000004079", - "0000004119", - "0000004139", - "0000004166", - "0000004167", - "0000004192", - "0000004223", - "0000004227", - "0000004287", - "0000004302", - "0000004362", - "0000004382", - "0000004395", - "0000004435", - "0000004456", - "0000004509", - "0000004546", - "0000004565", - "0000004578", - "0000004687", - "0000004763", - "0000004769", - "0000004799", - "0000004841", - "0000004850", - "0000004859", - "0000004863", - "0000004867", - "0000004869", - "0000004890", - "0000004911", - "0000004942", - "0000004947", - "0000004970", - "0000005007", - "0000005017", - "0000005021", - "0000005022", - "0000005046", - "0000005051", - "0000005114", - "0000005139", - "0000005143", - "0000005164", - "0000005167", - "0000005194", - "0000005207", - "0000005211", - "0000005245", - "0000005265", - "0000005322", - "0000005323", - "0000005444", - "0000005462", - "0000005476", - "0000005575", - "0000005606", - "0000005669", - "0000005684", - "0000005697", - "0000005722", - "0000005771", - "0000005776", - "0000005789", - "0000005798", - "0000005869", - "0000005875", - "0000005938", - "0000006022", - "0000006026", - "0000006028", - "0000006052", - "0000006066", - "0000006080", - "0000006095", - "0000006121", - "0000006127", - "0000006139", - "0000006195", - "0000006214", - "0000006264", - "0000006277", - "0000006297", - "0000006362", - "0000006366", - "0000006370", - "0000006403", - "0000006408", - "0000006411", - "0000006466", - "0000006468", - "0000006493", - "0000006497", - "0000006500", - "0000006518", - "0000006544", - "0000006600", - "0000006666", - "0000006667", - "0000006704", - "0000006734", - "0000006800", - "0000006819", - "0000006837", - "0000006882", - "0000006906", - "0000006917", - "0000006924", - "0000006945", - "0000006968", - "0000006990", - "0000007004", - "0000007076", - "0000007080", - "0000007178", - "0000007210", - "0000007238", - "0000007262", - "0000007280", - "0000007298", - "0000007305", - "0000007364", - "0000007379", - "0000007382", - "0000007394", - "0000007441", - "0000007458", - "0000007459", - "0000007464", - "0000007465", - "0000007515", - "0000007521", - "0000007530", - "0000007537", - "0000007545", - "0000007604", - "0000007614", - "0000007626", - "0000007640", - "0000007680", - "0000007696", - "0000007701", - "0000007707", - "0000007732", - "0000007738", - "0000007773", - "0000007800", - "0000007813", - "0000007817", - "0000007831", - "0000007853", - "0000007886", - "0000008007", - "0000008021", - "0000008072", - "0000008107", - "0000008128", - "0000008146", - "0000008167", - "0000008232", - "0000008282", - "0000008314", - "0000008324", - "0000008363", - "0000008366", - "0000008404", - "0000008431", - "0000008451", - "0000008475", - "0000008533", - "0000008562", - "0000008583", - "0000008613", - "0000008654", - "0000008702", - "0000008709", - "0000008727", - "0000008730", - "0000008745", - "0000008755", - "0000008780", - "0000008827", - "0000008942", - "0000008948", - "0000008973", - "0000008988", - "0000009004", - "0000009024", - "0000009044", - "0000009050", - "0000009083", - "0000009147", - "0000009149", - "0000009153", - "0000009167", - "0000009209", - "0000009229", - "0000009262", - "0000009297", - "0000009406", - "0000009435", - "0000009582", - "0000009621", - "0000009630", - "0000009645", - "0000009655", - "0000009668", - "0000009672", - "0000009679", - "0000009714", - "0000009724", - "0000009739", - "0000009746", - "0000009784", - "0000009816", - "0000009846", - "0000009879", - "0000009888", - "0000009895", - "0000009904", - "0000009926", - "0000009955", - "0000009961", - "0000009986" - ], - "fields_used": [ - "consolidated_text", - "order_to_delivery_days", - "delivery_to_invoice_days", - "order_to_invoice_days", - "delay_from_requested_days" - ], - "sample_size": 361, - "total_population": 10000 - }, - "cluster_id": "6", - "created_at": "2025-12-27T23:53:08.568772Z", - "is_notable": false, - "full_evidence": { - "doc_keys": [ - "0000000100", - "0000000112", - "0000000148", - "0000000163", - "0000000219", - "0000000246", - "0000000253", - "0000000331", - "0000000367", - "0000000427", - "0000000439", - "0000000503", - "0000000572", - "0000000595", - "0000000599", - "0000000642", - "0000000643", - "0000000676", - "0000000702", - "0000000730", - "0000000809", - "0000000831", - "0000000842", - "0000000852", - "0000000889", - "0000000933", - "0000000947", - "0000000980", - "0000001002", - "0000001023", - "0000001077", - "0000001137", - "0000001157", - "0000001186", - "0000001228", - "0000001260", - "0000001272", - "0000001288", - "0000001299", - "0000001361", - "0000001411", - "0000001451", - "0000001454", - "0000001472", - "0000001486", - "0000001533", - "0000001553", - "0000001560", - "0000001601", - "0000001605", - "0000001613", - "0000001645", - "0000001650", - "0000001745", - "0000001787", - "0000001857", - "0000001876", - "0000001896", - "0000001898", - "0000001932", - "0000001933", - "0000002008", - "0000002151", - "0000002165", - "0000002182", - "0000002192", - "0000002217", - "0000002282", - "0000002286", - "0000002306", - "0000002324", - "0000002467", - "0000002521", - "0000002553", - "0000002566", - "0000002581", - "0000002583", - "0000002588", - "0000002666", - "0000002696", - "0000002703", - "0000002733", - "0000002826", - "0000002863", - "0000002876", - "0000002890", - "0000002904", - "0000002953", - "0000003048", - "0000003067", - "0000003086", - "0000003132", - "0000003161", - "0000003165", - "0000003204", - "0000003319", - "0000003362", - "0000003393", - "0000003419", - "0000003430", - "0000003446", - "0000003453", - "0000003469", - "0000003483", - "0000003488", - "0000003504", - "0000003514", - "0000003515", - "0000003552", - "0000003557", - "0000003567", - "0000003613", - "0000003614", - "0000003617", - "0000003650", - "0000003660", - "0000003668", - "0000003686", - "0000003706", - "0000003823", - "0000003830", - "0000003849", - "0000003858", - "0000003868", - "0000003890", - "0000003912", - "0000003931", - "0000003957", - "0000003979", - "0000004000", - "0000004003", - "0000004008", - "0000004023", - "0000004051", - "0000004057", - "0000004070", - "0000004075", - "0000004079", - "0000004119", - "0000004139", - "0000004166", - "0000004167", - "0000004192", - "0000004223", - "0000004227", - "0000004287", - "0000004302", - "0000004362", - "0000004382", - "0000004395", - "0000004435", - "0000004456", - "0000004509", - "0000004546", - "0000004565", - "0000004578", - "0000004687", - "0000004763", - "0000004769", - "0000004799", - "0000004841", - "0000004850", - "0000004859", - "0000004863", - "0000004867", - "0000004869", - "0000004890", - "0000004911", - "0000004942", - "0000004947", - "0000004970", - "0000005007", - "0000005017", - "0000005021", - "0000005022", - "0000005046", - "0000005051", - "0000005114", - "0000005139", - "0000005143", - "0000005164", - "0000005167", - "0000005194", - "0000005207", - "0000005211", - "0000005245", - "0000005265", - "0000005322", - "0000005323", - "0000005444", - "0000005462", - "0000005476", - "0000005575", - "0000005606", - "0000005669", - "0000005684", - "0000005697", - "0000005722", - "0000005771", - "0000005776", - "0000005789", - "0000005798", - "0000005869", - "0000005875", - "0000005938", - "0000006022", - "0000006026", - "0000006028", - "0000006052", - "0000006066", - "0000006080", - "0000006095", - "0000006121", - "0000006127", - "0000006139", - "0000006195", - "0000006214", - "0000006264", - "0000006277", - "0000006297", - "0000006362", - "0000006366", - "0000006370", - "0000006403", - "0000006408", - "0000006411", - "0000006466", - "0000006468", - "0000006493", - "0000006497", - "0000006500", - "0000006518", - "0000006544", - "0000006600", - "0000006666", - "0000006667", - "0000006704", - "0000006734", - "0000006800", - "0000006819", - "0000006837", - "0000006882", - "0000006906", - "0000006917", - "0000006924", - "0000006945", - "0000006968", - "0000006990", - "0000007004", - "0000007076", - "0000007080", - "0000007178", - "0000007210", - "0000007238", - "0000007262", - "0000007280", - "0000007298", - "0000007305", - "0000007364", - "0000007379", - "0000007382", - "0000007394", - "0000007441", - "0000007458", - "0000007459", - "0000007464", - "0000007465", - "0000007515", - "0000007521", - "0000007530", - "0000007537", - "0000007545", - "0000007604", - "0000007614", - "0000007626", - "0000007640", - "0000007680", - "0000007696", - "0000007701", - "0000007707", - "0000007732", - "0000007738", - "0000007773", - "0000007800", - "0000007813", - "0000007817", - "0000007831", - "0000007853", - "0000007886", - "0000008007", - "0000008021", - "0000008072", - "0000008107", - "0000008128", - "0000008146", - "0000008167", - "0000008232", - "0000008282", - "0000008314", - "0000008324", - "0000008363", - "0000008366", - "0000008404", - "0000008431", - "0000008451", - "0000008475", - "0000008533", - "0000008562", - "0000008583", - "0000008613", - "0000008654", - "0000008702", - "0000008709", - "0000008727", - "0000008730", - "0000008745", - "0000008755", - "0000008780", - "0000008827", - "0000008942", - "0000008948", - "0000008973", - "0000008988", - "0000009004", - "0000009024", - "0000009044", - "0000009050", - "0000009083", - "0000009147", - "0000009149", - "0000009153", - "0000009167", - "0000009209", - "0000009229", - "0000009262", - "0000009297", - "0000009406", - "0000009435", - "0000009582", - "0000009621", - "0000009630", - "0000009645", - "0000009655", - "0000009668", - "0000009672", - "0000009679", - "0000009714", - "0000009724", - "0000009739", - "0000009746", - "0000009784", - "0000009816", - "0000009846", - "0000009879", - "0000009888", - "0000009895", - "0000009904", - "0000009926", - "0000009955", - "0000009961", - "0000009986" - ], - "n_documents": 361, - "field_usage": [ - { - "field_name": "consolidated_text", - "source_type": "unified", - "usage_type": "text", - "n_non_null": 361, - "n_total": 361, - "coverage": 1.0 - }, - { - "field_name": "order_to_delivery_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 344, - "n_total": 361, - "coverage": 0.9529085872576177 - }, - { - "field_name": "delivery_to_invoice_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 0, - "n_total": 361, - "coverage": 0.0 - }, - { - "field_name": "order_to_invoice_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 330, - "n_total": 361, - "coverage": 0.9141274238227147 - }, - { - "field_name": "delay_from_requested_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 0, - "n_total": 361, - "coverage": 0.0 - } - ], - "row_counts": { - "total_documents": 10000, - "cluster_documents": 361 - }, - "sampling_warnings": [], - "reproducibility": { - "random_seed": 42, - "clustering_algorithm": "kmeans", - "embedding_model": "tfidf", - "n_clusters": 8, - "min_cluster_size": 5, - "delay_threshold_days": 7, - "analysis_timestamp": "2025-12-27T23:53:08.568445Z", - "package_version": "0.1.0", - "parameters": {} - }, - "source_files": [ - "../synthetic-data/sample_output/orders.json", - "../synthetic-data/sample_output/deliveries.json", - "../synthetic-data/sample_output/invoices.json", - "../synthetic-data/sample_output/doc_flows.json", - "../synthetic-data/sample_output/customers.json", - "../synthetic-data/sample_output/materials.json" - ], - "has_warnings": false, - "validation_issues": [ - "Low coverage (0%) for field delivery_to_invoice_days", - "Low coverage (0%) for field delay_from_requested_days" - ] - } - }, - { - "id": "PAT-119F3CBF", - "title": "Ref / Order Ref / Stock Ref", - "description": "Documents in this cluster frequently contain \"ref\", \"order ref\", \"stock ref\". No statistically significant timing differences from baseline. Based on analysis of 288 documents.", - "top_phrases": [ - "ref", - "order ref", - "stock ref", - "order", - "rush", - "backorder ref", - "rush ref", - "hold ref", - "discount ref", - "stock" - ], - "sample_snippets": [], - "occurrence": { - "count": 288, - "by_sales_org": { - "3000": 96, - "2000": 97, - "1000": 95 - }, - "by_customer_industry": { - "RETAIL": 71, - "GOVERNMENT": 65, - "INDUSTRIAL": 83, - "WHOLESALE": 69 - } - }, - "effect": {}, - "effects": [], - "confidence": "MEDIUM", - "confidence_score": 0.4, - "caveats": [ - "Observational analysis only; correlation does not imply causation.", - "Patterns based on text similarity; may not capture all relevant factors.", - "No statistically significant effects detected." - ], - "evidence": { - "doc_keys": [ - "0000000003", - "0000000046", - "0000000082", - "0000000094", - "0000000107", - "0000000197", - "0000000268", - "0000000272", - "0000000285", - "0000000663", - "0000000664", - "0000000724", - "0000000752", - "0000000796", - "0000000850", - "0000000857", - "0000000913", - "0000000940", - "0000000950", - "0000000971", - "0000000981", - "0000001000", - "0000001075", - "0000001078", - "0000001102", - "0000001142", - "0000001174", - "0000001178", - "0000001284", - "0000001341", - "0000001349", - "0000001367", - "0000001400", - "0000001402", - "0000001416", - "0000001424", - "0000001485", - "0000001504", - "0000001545", - "0000001549", - "0000001580", - "0000001609", - "0000001616", - "0000001652", - "0000001671", - "0000001674", - "0000001700", - "0000001711", - "0000001722", - "0000001871", - "0000001989", - "0000002060", - "0000002066", - "0000002112", - "0000002163", - "0000002200", - "0000002204", - "0000002251", - "0000002288", - "0000002354", - "0000002423", - "0000002424", - "0000002551", - "0000002556", - "0000002622", - "0000002675", - "0000002699", - "0000002775", - "0000002798", - "0000002801", - "0000002818", - "0000002849", - "0000002938", - "0000002989", - "0000002990", - "0000003008", - "0000003030", - "0000003069", - "0000003075", - "0000003142", - "0000003170", - "0000003171", - "0000003267", - "0000003304", - "0000003333", - "0000003342", - "0000003365", - "0000003403", - "0000003424", - "0000003490", - "0000003550", - "0000003608", - "0000003611", - "0000003623", - "0000003634", - "0000003640", - "0000003652", - "0000003657", - "0000003802", - "0000003833", - "0000003850", - "0000003875", - "0000003956", - "0000004093", - "0000004147", - "0000004196", - "0000004285", - "0000004296", - "0000004361", - "0000004375", - "0000004389", - "0000004465", - "0000004501", - "0000004506", - "0000004538", - "0000004582", - "0000004601", - "0000004649", - "0000004659", - "0000004702", - "0000004710", - "0000004729", - "0000004773", - "0000004779", - "0000004842", - "0000004935", - "0000004996", - "0000005004", - "0000005068", - "0000005078", - "0000005096", - "0000005098", - "0000005115", - "0000005144", - "0000005149", - "0000005150", - "0000005225", - "0000005226", - "0000005309", - "0000005331", - "0000005346", - "0000005362", - "0000005367", - "0000005372", - "0000005377", - "0000005404", - "0000005423", - "0000005450", - "0000005547", - "0000005600", - "0000005640", - "0000005673", - "0000005676", - "0000005702", - "0000005741", - "0000005784", - "0000005793", - "0000005877", - "0000005935", - "0000005944", - "0000005973", - "0000006023", - "0000006069", - "0000006075", - "0000006083", - "0000006137", - "0000006166", - "0000006252", - "0000006314", - "0000006368", - "0000006372", - "0000006384", - "0000006424", - "0000006445", - "0000006478", - "0000006482", - "0000006501", - "0000006530", - "0000006532", - "0000006547", - "0000006573", - "0000006709", - "0000006717", - "0000006724", - "0000006746", - "0000006865", - "0000006916", - "0000006938", - "0000006949", - "0000006951", - "0000006974", - "0000007053", - "0000007168", - "0000007185", - "0000007226", - "0000007304", - "0000007309", - "0000007334", - "0000007341", - "0000007448", - "0000007475", - "0000007505", - "0000007572", - "0000007582", - "0000007630", - "0000007655", - "0000007672", - "0000007703", - "0000007713", - "0000007746", - "0000007751", - "0000007776", - "0000007842", - "0000007903", - "0000007907", - "0000007910", - "0000007927", - "0000007946", - "0000007952", - "0000007961", - "0000007982", - "0000008055", - "0000008088", - "0000008110", - "0000008118", - "0000008126", - "0000008127", - "0000008156", - "0000008163", - "0000008216", - "0000008222", - "0000008249", - "0000008255", - "0000008308", - "0000008335", - "0000008362", - "0000008449", - "0000008486", - "0000008521", - "0000008546", - "0000008623", - "0000008668", - "0000008693", - "0000008714", - "0000008721", - "0000008726", - "0000008760", - "0000008767", - "0000008784", - "0000008849", - "0000008850", - "0000008864", - "0000008877", - "0000008897", - "0000008903", - "0000008917", - "0000008930", - "0000008974", - "0000008990", - "0000009134", - "0000009143", - "0000009176", - "0000009244", - "0000009270", - "0000009310", - "0000009316", - "0000009317", - "0000009358", - "0000009362", - "0000009375", - "0000009472", - "0000009483", - "0000009493", - "0000009518", - "0000009527", - "0000009533", - "0000009558", - "0000009610", - "0000009627", - "0000009641", - "0000009686", - "0000009711", - "0000009796", - "0000009839", - "0000009843", - "0000009869", - "0000009951", - "0000009976" - ], - "fields_used": [ - "consolidated_text", - "order_to_delivery_days", - "delivery_to_invoice_days", - "order_to_invoice_days", - "delay_from_requested_days" - ], - "sample_size": 288, - "total_population": 10000 - }, - "cluster_id": "7", - "created_at": "2025-12-27T23:53:08.575072Z", - "is_notable": false, - "full_evidence": { - "doc_keys": [ - "0000000003", - "0000000046", - "0000000082", - "0000000094", - "0000000107", - "0000000197", - "0000000268", - "0000000272", - "0000000285", - "0000000663", - "0000000664", - "0000000724", - "0000000752", - "0000000796", - "0000000850", - "0000000857", - "0000000913", - "0000000940", - "0000000950", - "0000000971", - "0000000981", - "0000001000", - "0000001075", - "0000001078", - "0000001102", - "0000001142", - "0000001174", - "0000001178", - "0000001284", - "0000001341", - "0000001349", - "0000001367", - "0000001400", - "0000001402", - "0000001416", - "0000001424", - "0000001485", - "0000001504", - "0000001545", - "0000001549", - "0000001580", - "0000001609", - "0000001616", - "0000001652", - "0000001671", - "0000001674", - "0000001700", - "0000001711", - "0000001722", - "0000001871", - "0000001989", - "0000002060", - "0000002066", - "0000002112", - "0000002163", - "0000002200", - "0000002204", - "0000002251", - "0000002288", - "0000002354", - "0000002423", - "0000002424", - "0000002551", - "0000002556", - "0000002622", - "0000002675", - "0000002699", - "0000002775", - "0000002798", - "0000002801", - "0000002818", - "0000002849", - "0000002938", - "0000002989", - "0000002990", - "0000003008", - "0000003030", - "0000003069", - "0000003075", - "0000003142", - "0000003170", - "0000003171", - "0000003267", - "0000003304", - "0000003333", - "0000003342", - "0000003365", - "0000003403", - "0000003424", - "0000003490", - "0000003550", - "0000003608", - "0000003611", - "0000003623", - "0000003634", - "0000003640", - "0000003652", - "0000003657", - "0000003802", - "0000003833", - "0000003850", - "0000003875", - "0000003956", - "0000004093", - "0000004147", - "0000004196", - "0000004285", - "0000004296", - "0000004361", - "0000004375", - "0000004389", - "0000004465", - "0000004501", - "0000004506", - "0000004538", - "0000004582", - "0000004601", - "0000004649", - "0000004659", - "0000004702", - "0000004710", - "0000004729", - "0000004773", - "0000004779", - "0000004842", - "0000004935", - "0000004996", - "0000005004", - "0000005068", - "0000005078", - "0000005096", - "0000005098", - "0000005115", - "0000005144", - "0000005149", - "0000005150", - "0000005225", - "0000005226", - "0000005309", - "0000005331", - "0000005346", - "0000005362", - "0000005367", - "0000005372", - "0000005377", - "0000005404", - "0000005423", - "0000005450", - "0000005547", - "0000005600", - "0000005640", - "0000005673", - "0000005676", - "0000005702", - "0000005741", - "0000005784", - "0000005793", - "0000005877", - "0000005935", - "0000005944", - "0000005973", - "0000006023", - "0000006069", - "0000006075", - "0000006083", - "0000006137", - "0000006166", - "0000006252", - "0000006314", - "0000006368", - "0000006372", - "0000006384", - "0000006424", - "0000006445", - "0000006478", - "0000006482", - "0000006501", - "0000006530", - "0000006532", - "0000006547", - "0000006573", - "0000006709", - "0000006717", - "0000006724", - "0000006746", - "0000006865", - "0000006916", - "0000006938", - "0000006949", - "0000006951", - "0000006974", - "0000007053", - "0000007168", - "0000007185", - "0000007226", - "0000007304", - "0000007309", - "0000007334", - "0000007341", - "0000007448", - "0000007475", - "0000007505", - "0000007572", - "0000007582", - "0000007630", - "0000007655", - "0000007672", - "0000007703", - "0000007713", - "0000007746", - "0000007751", - "0000007776", - "0000007842", - "0000007903", - "0000007907", - "0000007910", - "0000007927", - "0000007946", - "0000007952", - "0000007961", - "0000007982", - "0000008055", - "0000008088", - "0000008110", - "0000008118", - "0000008126", - "0000008127", - "0000008156", - "0000008163", - "0000008216", - "0000008222", - "0000008249", - "0000008255", - "0000008308", - "0000008335", - "0000008362", - "0000008449", - "0000008486", - "0000008521", - "0000008546", - "0000008623", - "0000008668", - "0000008693", - "0000008714", - "0000008721", - "0000008726", - "0000008760", - "0000008767", - "0000008784", - "0000008849", - "0000008850", - "0000008864", - "0000008877", - "0000008897", - "0000008903", - "0000008917", - "0000008930", - "0000008974", - "0000008990", - "0000009134", - "0000009143", - "0000009176", - "0000009244", - "0000009270", - "0000009310", - "0000009316", - "0000009317", - "0000009358", - "0000009362", - "0000009375", - "0000009472", - "0000009483", - "0000009493", - "0000009518", - "0000009527", - "0000009533", - "0000009558", - "0000009610", - "0000009627", - "0000009641", - "0000009686", - "0000009711", - "0000009796", - "0000009839", - "0000009843", - "0000009869", - "0000009951", - "0000009976" - ], - "n_documents": 288, - "field_usage": [ - { - "field_name": "consolidated_text", - "source_type": "unified", - "usage_type": "text", - "n_non_null": 288, - "n_total": 288, - "coverage": 1.0 - }, - { - "field_name": "order_to_delivery_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 281, - "n_total": 288, - "coverage": 0.9756944444444444 - }, - { - "field_name": "delivery_to_invoice_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 0, - "n_total": 288, - "coverage": 0.0 - }, - { - "field_name": "order_to_invoice_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 274, - "n_total": 288, - "coverage": 0.9513888888888888 - }, - { - "field_name": "delay_from_requested_days", - "source_type": "timing", - "usage_type": "timing", - "n_non_null": 0, - "n_total": 288, - "coverage": 0.0 - } - ], - "row_counts": { - "total_documents": 10000, - "cluster_documents": 288 - }, - "sampling_warnings": [], - "reproducibility": { - "random_seed": 42, - "clustering_algorithm": "kmeans", - "embedding_model": "tfidf", - "n_clusters": 8, - "min_cluster_size": 5, - "delay_threshold_days": 7, - "analysis_timestamp": "2025-12-27T23:53:08.574973Z", - "package_version": "0.1.0", - "parameters": {} - }, - "source_files": [ - "../synthetic-data/sample_output/orders.json", - "../synthetic-data/sample_output/deliveries.json", - "../synthetic-data/sample_output/invoices.json", - "../synthetic-data/sample_output/doc_flows.json", - "../synthetic-data/sample_output/customers.json", - "../synthetic-data/sample_output/materials.json" - ], - "has_warnings": false, - "validation_issues": [ - "Low coverage (0%) for field delivery_to_invoice_days", - "Low coverage (0%) for field delay_from_requested_days" - ] - } - } - ] -} \ No newline at end of file diff --git a/pattern-engine/test_output/pattern_cards.md b/pattern-engine/test_output/pattern_cards.md deleted file mode 100644 index 1ebd30a..0000000 --- a/pattern-engine/test_output/pattern_cards.md +++ /dev/null @@ -1,335 +0,0 @@ -# SAP Workflow Mining Pattern Report - -**Generated**: 2025-12-27T23:53:08.577572Z -**Version**: 0.1.0 -**Random Seed**: 42 - -## Summary - -- **Total Patterns**: 8 -- **Notable Patterns**: 0 -- **Total Documents**: 2913 -- **Average Confidence**: 40% - -## Other Patterns - -## Mgmt Approved / Mgmt / Approved - -**ID**: PAT-F22349FF -**Confidence**: 40% -**Sample Size**: 347 documents - -### Description -Documents in this cluster frequently contain "mgmt approved", "mgmt", "approved". No statistically significant timing differences from baseline. Based on analysis of 347 documents. - -### Characteristic Phrases -- mgmt approved -- mgmt -- approved -- expedite mgmt approved -- expedite mgmt - -### Caveats -- Observational analysis only; correlation does not imply causation. -- Patterns based on text similarity; may not capture all relevant factors. -- No statistically significant effects detected. - -### Evidence Summary - -- **Documents**: 347 -- **Source Files**: 6 - -**Row Counts:** -- total_documents: 10,000 -- cluster_documents: 347 - -**Reproducibility:** -- Seed: 42 -- Algorithm: kmeans -- Embedding: tfidf -- Timestamp: 2025-12-27T23:53:08.524827Z - ---- - -## Needs Friday / Customer Needs Friday / Friday - -**ID**: PAT-7CF3DCD1 -**Confidence**: 40% -**Sample Size**: 360 documents - -### Description -Documents in this cluster frequently contain "needs friday", "customer needs friday", "friday". No statistically significant timing differences from baseline. Based on analysis of 360 documents. - -### Characteristic Phrases -- needs friday -- customer needs friday -- friday -- needs -- customer needs - -### Caveats -- Observational analysis only; correlation does not imply causation. -- Patterns based on text similarity; may not capture all relevant factors. -- No statistically significant effects detected. - -### Evidence Summary - -- **Documents**: 360 -- **Source Files**: 6 - -**Row Counts:** -- total_documents: 10,000 -- cluster_documents: 360 - -**Reproducibility:** -- Seed: 42 -- Algorithm: kmeans -- Embedding: tfidf -- Timestamp: 2025-12-27T23:53:08.530594Z - ---- - -## Hold / Credit / Credit Hold - -**ID**: PAT-76CDCA00 -**Confidence**: 40% -**Sample Size**: 141 documents - -### Description -Documents in this cluster frequently contain "hold", "credit", "credit hold". No statistically significant timing differences from baseline. Based on analysis of 141 documents. - -### Characteristic Phrases -- hold -- credit -- credit hold -- hold expedite -- hold credit - -### Caveats -- Observational analysis only; correlation does not imply causation. -- Patterns based on text similarity; may not capture all relevant factors. -- No statistically significant effects detected. - -### Evidence Summary - -- **Documents**: 141 -- **Source Files**: 6 - -**Row Counts:** -- total_documents: 10,000 -- cluster_documents: 141 - -**Reproducibility:** -- Seed: 42 -- Algorithm: kmeans -- Embedding: tfidf -- Timestamp: 2025-12-27T23:53:08.534528Z - ---- - -## Rush / Order / Backorder - -**ID**: PAT-CF84D0A6 -**Confidence**: 40% -**Sample Size**: 819 documents - -### Description -Documents in this cluster frequently contain "rush", "order", "backorder". No statistically significant timing differences from baseline. Based on analysis of 819 documents. - -### Characteristic Phrases -- rush -- order -- backorder -- 01 -- 03 - -### Caveats -- Observational analysis only; correlation does not imply causation. -- Patterns based on text similarity; may not capture all relevant factors. -- No statistically significant effects detected. - -### Evidence Summary - -- **Documents**: 819 -- **Source Files**: 6 - -**Row Counts:** -- total_documents: 10,000 -- cluster_documents: 819 - -**Reproducibility:** -- Seed: 42 -- Algorithm: kmeans -- Embedding: tfidf -- Timestamp: 2025-12-27T23:53:08.547803Z - ---- - -## Expedite / Expedite Ref / Expedite Expedite - -**ID**: PAT-43D46B4A -**Confidence**: 40% -**Sample Size**: 402 documents - -### Description -Documents in this cluster frequently contain "expedite", "expedite ref", "expedite expedite". No statistically significant timing differences from baseline. Based on analysis of 402 documents. - -### Characteristic Phrases -- expedite -- expedite ref -- expedite expedite -- order expedite -- discount expedite - -### Caveats -- Observational analysis only; correlation does not imply causation. -- Patterns based on text similarity; may not capture all relevant factors. -- No statistically significant effects detected. - -### Evidence Summary - -- **Documents**: 402 -- **Source Files**: 6 - -**Row Counts:** -- total_documents: 10,000 -- cluster_documents: 402 - -**Reproducibility:** -- Seed: 42 -- Algorithm: kmeans -- Embedding: tfidf -- Timestamp: 2025-12-27T23:53:08.552691Z - ---- - -## Partial / Ship / Partial Ship - -**ID**: PAT-4DC2ADD9 -**Confidence**: 40% -**Sample Size**: 195 documents - -### Description -Documents in this cluster frequently contain "partial", "ship", "partial ship". No statistically significant timing differences from baseline. Based on analysis of 195 documents. - -### Characteristic Phrases -- partial -- ship -- partial ship -- shipment ok -- ok - -### Caveats -- Observational analysis only; correlation does not imply causation. -- Patterns based on text similarity; may not capture all relevant factors. -- No statistically significant effects detected. - -### Evidence Summary - -- **Documents**: 195 -- **Source Files**: 6 - -**Row Counts:** -- total_documents: 10,000 -- cluster_documents: 195 - -**Reproducibility:** -- Seed: 42 -- Algorithm: kmeans -- Embedding: tfidf -- Timestamp: 2025-12-27T23:53:08.556665Z - ---- - -## Request / Customer Request / Customer - -**ID**: PAT-8BB0F9C7 -**Confidence**: 40% -**Sample Size**: 361 documents - -### Description -Documents in this cluster frequently contain "request", "customer request", "customer". No statistically significant timing differences from baseline. Based on analysis of 361 documents. - -### Characteristic Phrases -- request -- customer request -- customer -- expedite customer request -- expedite customer - -### Caveats -- Observational analysis only; correlation does not imply causation. -- Patterns based on text similarity; may not capture all relevant factors. -- No statistically significant effects detected. - -### Evidence Summary - -- **Documents**: 361 -- **Source Files**: 6 - -**Row Counts:** -- total_documents: 10,000 -- cluster_documents: 361 - -**Reproducibility:** -- Seed: 42 -- Algorithm: kmeans -- Embedding: tfidf -- Timestamp: 2025-12-27T23:53:08.568445Z - ---- - -## Ref / Order Ref / Stock Ref - -**ID**: PAT-119F3CBF -**Confidence**: 40% -**Sample Size**: 288 documents - -### Description -Documents in this cluster frequently contain "ref", "order ref", "stock ref". No statistically significant timing differences from baseline. Based on analysis of 288 documents. - -### Characteristic Phrases -- ref -- order ref -- stock ref -- order -- rush - -### Caveats -- Observational analysis only; correlation does not imply causation. -- Patterns based on text similarity; may not capture all relevant factors. -- No statistically significant effects detected. - -### Evidence Summary - -- **Documents**: 288 -- **Source Files**: 6 - -**Row Counts:** -- total_documents: 10,000 -- cluster_documents: 288 - -**Reproducibility:** -- Seed: 42 -- Algorithm: kmeans -- Embedding: tfidf -- Timestamp: 2025-12-27T23:53:08.574973Z - ---- - -## Appendix: Reproducibility - -To reproduce this analysis: - -```bash -python -m pattern_engine run --seed 42 \ - --input-dir ./data --output-dir ./output -``` - -### Parameters Used - -- Clustering Algorithm: kmeans -- Embedding Model: tfidf -- Number of Clusters: 8 -- Minimum Cluster Size: 5 -- Delay Threshold: 7 days \ No newline at end of file diff --git a/pattern-engine/tests/test_csv_loader.py b/pattern-engine/tests/test_csv_loader.py index b0c3a2c..ccb0eb5 100644 --- a/pattern-engine/tests/test_csv_loader.py +++ b/pattern-engine/tests/test_csv_loader.py @@ -426,6 +426,28 @@ def test_european_number_format(self): assert loader._clean_value('1234,56') == 1234.56 assert loader._clean_value('1000') == 1000 + def test_thousands_and_decimal_separators(self): + """Regression: grouped amounts must not collapse 1000x (both US and EU). + + The previous _clean_value turned '1.234,56' into 1.23456. + """ + loader = CSVLoader() + + # European: period thousands, comma decimal. + assert loader._clean_value('1.234,56') == pytest.approx(1234.56) + assert loader._clean_value('1.234.567,89') == pytest.approx(1234567.89) + + # US/standard: comma thousands, period decimal. + assert loader._clean_value('1,234.56') == pytest.approx(1234.56) + assert loader._clean_value('1,234,567.89') == pytest.approx(1234567.89) + + # Plain decimal, unchanged. + assert loader._clean_value('1234.56') == pytest.approx(1234.56) + + # The specific values must be > 1000, not the ~1.2 the old bug produced. + assert loader._clean_value('1.234,56') > 1000 + assert loader._clean_value('1,234.56') > 1000 + def test_reproducible_text_generation(self): """Test that synthetic text generation is reproducible with same seed.""" with tempfile.TemporaryDirectory() as tmpdir: diff --git a/viewer/package-lock.json b/viewer/package-lock.json index 2e776f9..e7ca145 100644 --- a/viewer/package-lock.json +++ b/viewer/package-lock.json @@ -1,12 +1,12 @@ { "name": "transaction-forensics-viewer", - "version": "1.0.1", + "version": "3.0.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "transaction-forensics-viewer", - "version": "1.0.1", + "version": "3.0.1", "license": "MIT", "dependencies": { "express": "^4.18.2" diff --git a/viewer/package.json b/viewer/package.json index 48ef9cb..b3fca98 100644 --- a/viewer/package.json +++ b/viewer/package.json @@ -1,6 +1,6 @@ { "name": "transaction-forensics-viewer", - "version": "1.0.1", + "version": "3.0.1", "description": "Web viewer for Transaction Forensics pattern cards", "main": "src/server.js", "scripts": {