Privacy-first Traditional Chinese / English AI safety framework for LLM-assisted workflows.
The problem: most LLM integrations send raw user data straight to the model and trust the output. That leaks PII, invents answers, and lets the model do things it shouldn't — especially dangerous in non-English, mixed-script environments where existing tooling is thin.
This repo's approach: deterministic rules run in front of every LLM call. Private data is filtered before the model sees it, replies must quote approved knowledge, and risky actions (auto-send, auto-merge, publish) require a human. Everything is plain Node.js with zero production dependencies and 2,000+ assertions — you can fork it, run npm test, and have passing guardrails in 30 seconds with no API key.
The patterns work for customer support (the original use case) and for OSS maintainer automation (PR review, issue triage, release safety). See the maintainer automation section below.
Local v1.0 workflow skeleton is complete:
customer channel
-> channel adapter
-> conversation context
-> privacy filter
-> privacy gateway
-> intent classifier
-> package ops context
-> knowledge base
-> promotion sync context
-> business rules
-> private business backend mock
-> model router
-> AI draft engine
-> safety checker
-> send reply or staff inbox
Current test total: 2,000+ assertions across 36 plain Node.js test files.
No npm dependencies are required. Everything is plain Node.js stdlib.
Most customer-support AI examples are English-first and prompt-first. This project is built around safer small-team adoption:
- PII before prompts: customer identifiers are redacted before any model boundary.
- Approved knowledge only: auto-send replies must quote approved business knowledge exactly.
- Rules beat prompts: booking, payment, refund, medical, legal, and financial boundaries live in deterministic JavaScript rules.
- Human-in-the-loop by default: risky or uncertain cases go to staff review instead of being sent automatically.
- Traditional Chinese / English examples: tests cover mixed-language customer-support intent, safety, and routing patterns.
The same guardrails that keep an AI customer-support reply safe — filter private data before the model, ground answers in approved knowledge, keep deterministic rules in front of LLM output, and require a human for risky actions — apply directly to maintaining an open-source project with AI assistance. The patterns here are reusable by other maintainers, independent of the customer-support domain.
A dependency-free starting point lives in
maintainer-automation/, with an example GitHub
Actions template in
examples/github-action-pr-review/ and an
adversarial test pack in
red-team-cases/oss-maintainer-security.md.
| Use case | How this repo's patterns apply |
|---|---|
| PR risk classification | classifyPullRequest flags changes to CI, deploy, lockfiles, and security policy as high-risk before review. |
| Issue triage | Route low-confidence or possible data-loss reports to a human instead of auto-labelling, the same way uncertain support messages go to staff. |
| Regression-test generation from bug reports | Generate tests from reports, but scan the generated fixture for secrets/PII and use fake data only before committing. |
| Release safety checks | Run a deterministic gate before tagging/publishing; require explicit maintainer approval for the publish step. |
| Privacy filtering before LLM calls | scanForSecretsAndPii strips secrets and personal data out of diffs, issues, and fixtures before any model sees them. |
| Prompt-injection red-teaming | Treat PR/issue/diff text as untrusted data; the red-team pack covers injection that tries to disable scans or force a merge. |
| Approved-knowledge grounding | Keep model review advisory and grounded in repo conventions rather than letting it invent policy. |
| Human review before risky automation | evaluateAutomation keeps auto-merge, auto-send, publish-release, and close-issue behind a human. |
| Security & code quality in small OSS projects | Deterministic, zero-dependency checks small teams can adopt without standing up extra infrastructure. |
The goal is modest and practical: let a small maintainer team use LLM help for review and triage without giving it the ability to merge, send, or publish something risky on its own.
| # | Module | Purpose |
|---|---|---|
| 1 | privacy filter ver 1.0 |
Redacts PII and flags locale-specific risk before any LLM call. |
| 2 | privacy gateway ver 1.0 |
Routes sanitized messages: send, review, or block. |
| 3 | intent classifier ver 1.0 |
Classifies Traditional Chinese / English / mixed enquiries into stable intents. |
| 4 | knowledge base ver 1.0 |
Approved-only business answers and grounding IDs. |
| 5 | business rules ver 1.0 |
Deterministic policy gate and capability contract. |
| 6 | google drive promo sync ver 1.0 |
Daily Google Drive promotion sync with configurable UTC+8 locale-time expiry checks. |
| 7 | AI draft engine ver 1.0 |
Produces grounded drafts or staff-only summaries. |
| 8 | safety checker ver 1.0 |
Re-validates drafts before anything can be sent. |
| 9 | channel adapter ver 1.0 |
Normalizes WhatsApp / IG / FB / website payloads and builds outbound payloads. |
| 10 | model router ver 1.0 |
Chooses no-LLM / Haiku / Sonnet by action and risk. |
| 11 | private business backend mock ver 1.0 |
Mock booking, order, stock, and payment facts. |
| 12 | staff inbox ver 1.0 |
In-memory review / handoff queue. |
| 13 | end-to-end pipeline ver 1.0 |
Orchestrates the whole local workflow. |
| 14 | conversation context ver 1.0 |
Shared deterministic stitching for fragmented booking follow-ups before the pipeline. |
git clone https://github.com/BOOK318/OSSsystem.git
cd OSSsystem
npm test # 36 test files, 2,000+ assertions, zero install
node examples/quick-demo.js # runs the full pipeline with fake dataThe demo drives five messages through the entire guardrail pipeline — privacy
filtering, intent classification, business rules, safety checks, and staff
handoff — using only the mock backend and a stubbed LLM adapter. No network, no
API key, no npm install.
Copy or edit the local environment file first:
cp .env.example .envOptional LLM adapter modes:
WA_LLM_ADAPTER=claude-apiwithANTHROPIC_API_KEYorCLAUDE_API_KEY.WA_LLM_ADAPTER=claudefor local OAuth-based Claude smoke testing.CODEX_LLM_AUTH_MODE=oauthwith a local Codex CLI session for Codex adapter smoke testing.
Start the local webhook server:
npm startBy default it listens at http://127.0.0.1:3000/webhook in unsigned local mode for restaurant_demo.
Opening that URL in a browser shows a local website chat simulator with fake customers, orders, payments, stock, and booking scenarios.
The fake database lives at:
private business backend mock ver 1.0/seed/mockBusinessData.js
Send a test message:
curl -X POST http://127.0.0.1:3000/webhook \
-H "content-type: application/json" \
-d '{"channel":"website","sessionId":"local-demo-001","text":"你哋幾點開門?"}'To run signed mode, set a webhook secret first:
WEBHOOK_SECRET="dev-secret" WEBHOOK_BUSINESS_ID="restaurant_demo" npm startDrive the pipeline directly with your own LLM adapter (or a stub, as below):
node - <<'NODE'
const { createPipeline } = require("./end-to-end pipeline ver 1.0/src/pipeline");
(async () => {
const pipeline = createPipeline({
llmAdapter: async (prompt, context) => {
if (context.decision.action === "handoff") {
return { text: "【員工交接】
意圖:" + context.intent.primaryIntent + "
建議下一步:由同事跟進。" };
}
return { text: context.knowledge.bestMatch?.answer || "請問你想了解哪一方面?" };
}
});
const result = await pipeline.runMessage({
channel: "website",
businessId: "restaurant_demo",
sessionId: "local-demo-001",
text: "你們幾點營業?"
});
console.log(JSON.stringify({
finalStatus: result.finalStatus,
action: result.decision.action,
intent: result.intent.primaryIntent,
safety: result.safety.verdict,
replyText: result.outbound?.payload?.text || result.draft?.text
}, null, 2));
})();
NODERun from the repo root:
node "privacy filter ver 1.0/test/privacyFilter.test.js"
node "privacy filter ver 1.0/test/privacyFilter.edge.test.js"
node "privacy gateway ver 1.0/test/privacyGateway.test.js"
node "conversation context ver 1.0/test/conversationContext.test.js"
node "intent classifier ver 1.0/test/intentClassifier.test.js"
node "intent classifier ver 1.0/test/intentClassifier.edge.test.js"
node "knowledge base ver 1.0/test/knowledgeBase.test.js"
node "business rules ver 1.0/test/businessRules.test.js"
node "google drive promo sync ver 1.0/test/promoSync.test.js"
node "AI draft engine ver 1.0/test/draftEngine.test.js"
node "safety checker ver 1.0/test/safetyChecker.test.js"
node "channel adapter ver 1.0/test/channelAdapter.test.js"
node "model router ver 1.0/test/modelRouter.test.js"
node "private business backend mock ver 1.0/test/businessBackendMock.test.js"
node "staff inbox ver 1.0/test/staffInbox.test.js"
node "end-to-end pipeline ver 1.0/test/pipeline.test.js"
node "end-to-end pipeline ver 1.0/test/server.test.js"The test runner discovers all *.test.js files outside ignored generated-output folders and runs each one with Node.
| businessId | Archetype |
|---|---|
beauty_demo |
beauty clinic |
restaurant_demo |
restaurant |
igshop_demo |
Instagram shop |
edu_demo |
education centre |
solara_bazi |
consultation page |
- Privacy gateway runs before any LLM call.
- Business policy lives in typed JS rules, not only prompts.
- Promotion expiry is checked using configurable UTC+8 locale time.
auto_sendmust quote approved KB text exactly.- Staff review is required for pricing, backend-bound actions, handoff, safety violations, and privacy blocks.
- Current channel/server/backend/staff inbox pieces are local skeletons, not production integrations.
This is an open-source project and contributions are welcome.
- Start here: CONTRIBUTING.md — setup, privacy/safety rules, and the PR checklist.
- How it fits together: docs/ARCHITECTURE.md.
- Where it's going / good first issues: ROADMAP.md.
- Be excellent to each other: CODE_OF_CONDUCT.md.
- Security & responsible disclosure: SECURITY.md.
All fixtures, tests, and examples must use fake data only (e.g. [email protected], +886900000000, ORDER_TEST_001). Never commit real customer data, secrets, or API keys.