Disclaimer: Independent educational project. Not affiliated with Finkraft.ai. Built by Kaushal Khodifad. Data from public sources; figures are estimates.return to portfolio
Disclaimer: Independent educational project. Not affiliated with Finkraft.ai.
Tab 2 of 34 partsPDF export ready

Product spec. GST reconciliation, IMS and a grounded AI knowledge base, in four parts.

Twenty reconciliation edge cases, a one-pager IMS PRD, a 7-tier matching algorithm with pseudo-code and confidence bands, and a RAG-style AI knowledge-base architecture with six guardrails. Cited against CGST sections and CBIC norms where relevant. Same dataset as Tab 3's working product - the spec and the product reinforce each other.

Anatomy of an edge case · read every card below against this key
5 fields · 20 cards
Failure pattern
what actually breaks the match
Detection rule
the check the engine runs to catch it
Auto-resolution
the decision + confidence, or escalate
Customer prompt
what the operator is asked, if human-needed
Audit fields
columns persisted for an ASMT-10 / DRC-01 reply
Part 1 · Reconciliation edge cases

Twenty failure patterns that break GSTR-2A/2B reconciliation.

For each: the failure pattern, the detection rule a recon engine should run, an auto-resolution decision (with confidence), the customer prompt when human attention is required, and the audit-trail fields the engine must persist so an ASMT-10 or DRC-01 response can reconstruct what happened.

20 cases · 5 over the “minimum 15” barAll grouped by 10 categoriesDrawn from real CBIC sections + GSP integration patterns
#01Identity

Supplier GSTIN typo (O vs 0, I vs 1)

Failure pattern
Supplier reports '29ABCDE1234F1Z5' but enters '29ABCDE1234F1ZS' (S vs 5). PR and 2B never match on GSTIN.
Detection rule
Levenshtein distance ≤ 1 between PR GSTIN and any 2B GSTIN of a similarly-named supplier; flag if same PAN segment (positions 3-12) but different last 3 chars.
Auto-resolution
Fuzzy-GSTIN match tier (60% confidence). Surface as 'GSTIN candidate' - do NOT auto-claim ITC.
Customer prompt
Possible GSTIN typo. Two candidates differ in 1 char. Confirm the right one or contact supplier.
Audit-trail fields
pr_gstin_raw2b_gstin_candidatelevenshtein_scoreoperator_decision
Reference
GSTIN format: GSTIN = 2-state + 10-PAN + 1-entity + Z + 1-check.
#02Format

Invoice number with leading zeros stripped by Excel

Failure pattern
Invoice is 'INV-0042' in supplier system. Excel CSV export strips zero → 'INV-42'. PR shows 'INV-42', 2B shows 'INV-0042'.
Detection rule
Normalized comparison (strip non-alphanumeric + lowercase + lpad numeric segments to common width).
Auto-resolution
Normalized match tier (95% confidence). Auto-accept if all other fields match exactly.
Customer prompt
(none - auto-resolved)
Audit-trail fields
pr_invoice_no_raw2b_invoice_no_rawnormalized_invoice_nonormalization_steps
#03Format

FY-rollover invoice number format change

Failure pattern
Supplier numbers as 'INV/24-25/001' in Mar 2025 and 'INV/2025-26/001' in Apr 2025. PR keeps old format.
Detection rule
On normalized mismatch, attempt FY-token substitution (24-25 ↔ 2024-25 ↔ FY24-25 ↔ 2024-2025); re-normalize + compare.
Auto-resolution
FY-aware normalized match (90% confidence). Auto-accept if amount + date within tolerance.
Customer prompt
Possible FY-format change. Review the suggested match.
Audit-trail fields
fy_token_beforefy_token_aftersubstitution_rule
#04Format

Special characters in invoice number

Failure pattern
'INV#001/A&B' vs 'INV001AB' - same invoice, different keyboard.
Detection rule
Strip [^A-Za-z0-9] in normalized comparison.
Auto-resolution
Normalized match (95% confidence). Auto-accept.
Customer prompt
(none - auto-resolved)
Audit-trail fields
pr_invoice_no_rawstripped_charsnormalized_invoice_no
#05Amount

Rounding-rule mismatch (₹1 difference)

Failure pattern
Supplier rounds at line level (₹49,999.50 → ₹50,000); PR rounds at invoice level (sum = ₹49,999). Tax also differs by ₹0.10.
Detection rule
Tolerance match: abs(pr_amount − 2b_amount) ≤ max(₹1, 0.01% of larger). Same tolerance on tax components.
Auto-resolution
Tolerance match (85% confidence). Auto-accept; flag for sample audit.
Customer prompt
(none - auto-resolved within ₹1 tolerance)
Audit-trail fields
pr_amount2b_amounttolerance_appliedtolerance_band
Reference
Per CGST Rule 88, tax amount may be rounded to nearest rupee.
#06Tax split

IGST vs CGST+SGST place-of-supply error

Failure pattern
Supplier in Karnataka invoices customer in Karnataka but reports IGST. Customer expected CGST+SGST in PR.
Detection rule
Compare first 2 chars of supplier GSTIN vs recipient GSTIN. If equal → expect CGST+SGST; else IGST. Mismatch + same total tax → flag as place-of-supply error.
Auto-resolution
Cannot auto-resolve - ITC eligibility differs by tax type. Surface to operator with both candidates.
Customer prompt
Possible place-of-supply error. Supplier reported IGST; expected CGST+SGST. Contact supplier to amend in GSTR-1.
Audit-trail fields
supplier_state_coderecipient_state_codepr_tax_split2b_tax_split
#07Timing

Supplier filed late, invoice in next-month 2B

Failure pattern
March invoice; supplier files GSTR-1 on Apr 17 (after Mar's 14th lock). Invoice appears in Apr 2B.
Detection rule
Multi-month lookback (±3 months) keyed on supplier GSTIN + normalized invoice no. Detect period drift.
Auto-resolution
Multi-month match tier (70% confidence). Auto-link with period-drift flag; ITC claimable in the new period only.
Customer prompt
Invoice found in a different period than expected. ITC moves to that filing period.
Audit-trail fields
pr_period2b_period_foundperiod_drift_monthssupplier_filing_date
Reference
ITC anchored to GSTR-2B per Section 16(2)(aa), Jan 2022.
#08Timing

FY-rollover timing edge

Failure pattern
Supplier files Mar 2025 invoice in Sep 2025. ITC eligibility window closes Nov 30 of next FY (or annual return, whichever earlier).
Detection rule
On multi-month match where period_drift causes invoice_date.fy ≠ filing.fy, validate against Section 16(4) cutoff.
Auto-resolution
If past Nov 30 cutoff: ITC permanently lost - mark unmatched + record-loss.
Customer prompt
Section 16(4) cutoff exceeded - this ITC is no longer claimable.
Audit-trail fields
invoice_fyfiling_fycutoff_dateineligibility_reason
Reference
CGST Section 16(4).
#09Lifecycle

Cancelled invoice still in PR

Failure pattern
Supplier issued invoice then cancelled (within 24h IRP window for e-invoices, or via credit note for non-e-inv). PR keeps the original; 2B never shows it.
Detection rule
Look for a credit-note from same supplier with matching reference within 60 days. If found → mark PR as cancelled.
Auto-resolution
If credit note found: auto-unmatch + flag for write-off. If not: surface to operator.
Customer prompt
No matching 2B entry. A credit note from this supplier may indicate cancellation - confirm with supplier.
Audit-trail fields
credit_note_idcancellation_dateirn_cancellation_status
#10Lifecycle

Amended invoice - vendor changed amount after acceptance

Failure pattern
Operator accepted invoice in March IMS. Supplier amends in April (new amount). 2B shows the amendment; PR unchanged.
Detection rule
Track 2B `amended` flag + `amendment_of` foreign key. On change to a previously-matched record, flag the existing match.
Auto-resolution
Auto-unmatch the prior decision, surface as 'amended' for re-review.
Customer prompt
Supplier amended this invoice. Original ITC will be reversed; review the new amount.
Audit-trail fields
original_match_idamendment_2b_idamount_deltaprevious_ims_state
#11Credit notes

Credit notes shown as negative amounts vs separate doc type

Failure pattern
Some suppliers report CN as negative invoice amounts in GSTR-1; some as separate doc type. PR and 2B differ in representation.
Detection rule
Treat any 2B row with `amount < 0` AND matching invoice reference as a credit note; merge with original for net ITC calc.
Auto-resolution
Net the credit note against original ITC; surface combined view.
Customer prompt
Credit note ₹X applied to original invoice ₹Y. Net ITC claim = ₹Z.
Audit-trail fields
original_invoice_idcredit_note_idnet_itcmerge_rule
#12Compliance

Section 17(5) ineligible ITC mistakenly claimed

Failure pattern
PR contains an invoice for a 7-seater company car ITC; reconciliation finds a 2B match. Naive recon claims it.
Detection rule
Run HSN/SAC code through 17(5) blocklist before claim; flag if blocked category.
Auto-resolution
Block ITC claim; surface as 'matched but ineligible'. Require operator override with reason.
Customer prompt
Matched ₹X but ITC blocked under Section 17(5). Reason: motor vehicle ≤ 13 seats. Override?
Audit-trail fields
hsn_sacblocked_categoryoperator_overrideoverride_reason
Reference
CGST Section 17(5)(a).
#13Compliance

RCM transactions misclassified

Failure pattern
GTA invoice (RCM under Sec 9(3)). Supplier reports normally; recipient owes the tax. Naive recon claims ITC against supplier's filing.
Detection rule
Maintain HSN/SAC + supplier-type → RCM mapping. Detect RCM-flagged PR rows; require self-invoice + cash-payment of tax before ITC.
Auto-resolution
Block ITC claim until self-invoice + cash payment recorded; then auto-claim next period.
Customer prompt
RCM transaction. Pay tax in cash this period; ITC claimable next period.
Audit-trail fields
rcm_applicableself_invoice_idcash_payment_idclaim_period
Reference
CGST Section 9(3) + 9(4).
#14Compliance

Composition-scheme supplier

Failure pattern
Supplier opted into composition; PR shows tax line. ITC always blocked for composition.
Detection rule
Lookup supplier composition status via GSTN portal (or cached). Block ITC if active.
Auto-resolution
Auto-block; surface with supplier-status badge.
Customer prompt
Supplier is under composition scheme - ITC blocked. Verify the invoice should show tax at all.
Audit-trail fields
composition_statusas_of_dateblocking_rule
Reference
CGST Section 10.
#15E-invoicing

E-invoice IRN mismatch with GSTR-1 entry

Failure pattern
Supplier generated IRN but GSTR-1 entry shows different invoice number (typo / different system).
Detection rule
Cross-check IRN feed vs GSTR-1; flag orphan IRNs (no GSTR-1 entry) and unsigned GSTR-1 (no IRN).
Auto-resolution
Surface mismatch with both records; require supplier-side fix.
Customer prompt
IRN found but supplier's GSTR-1 entry doesn't reference it. Ask supplier to align.
Audit-trail fields
irngstr1_invoice_noirp_invoice_nomismatch_type
#16E-invoicing

E-invoice cancelled after 24-hour window

Failure pattern
Supplier tried to cancel IRN after Day-2. Cancellation rejected; supplier issued credit note. PR has original.
Detection rule
Check IRN cancellation status. If still active but credit note exists → flag as effective cancellation.
Auto-resolution
Net against credit note; mark as effective-cancelled with both refs.
Customer prompt
IRN still live but credit note issued for full value. Net ITC = 0.
Audit-trail fields
irnirn_activecredit_note_ideffective_status
#17Reporting

B2C reported as B2B (GSTIN of recipient missing)

Failure pattern
Supplier reported sale without recipient GSTIN; appears in B2C section of GSTR-1 only. PR expects B2B entry.
Detection rule
If PR has supplier+invoice+amount but no 2B B2B match, scan supplier's GSTR-1 B2C summary for amount + period.
Auto-resolution
Cannot auto-resolve (B2C → no ITC). Flag for supplier amendment.
Customer prompt
Supplier reported as B2C. Request a B2B amendment with your GSTIN - ITC blocked until then.
Audit-trail fields
b2c_section_amountb2c_periodamendment_requested_at
#18Reporting

ISD distribution credit

Failure pattern
Head office distributes ITC via ISD invoice. Branch's PR shows ISD credit; 2B section is different (ISDA).
Detection rule
Distinguish ISDA-section invoices in 2B; match against ISD invoices in PR with separate logic (no commercial cross-match).
Auto-resolution
Auto-link if ISD distribution number matches.
Customer prompt
(none - auto-resolved if distribution # matches)
Audit-trail fields
isd_distribution_noisd_invoice_idbranch_gstin
Reference
CGST Section 20 + Rule 39.
#19Reporting

Advance payment voucher mismatch

Failure pattern
Customer paid advance; supplier issued advance receipt voucher (no ITC); later issued invoice. PR may have both.
Detection rule
Detect advance-receipt vouchers (separate doc type); ensure ITC claim only on final invoice, not advance.
Auto-resolution
Block ITC on advance voucher; pair to final invoice for traceability.
Customer prompt
Advance voucher detected. ITC claimable only on the final invoice.
Audit-trail fields
advance_voucher_idfinal_invoice_idpaired_at
#20Reporting

TDS/TCS confusion with GST tax

Failure pattern
Customer-side TDS under GST (Section 51) shows as a reduction; finance team confuses it with input tax.
Detection rule
Segregate TDS/TCS lines (filed in GSTR-7/8) from GST tax lines; never include in ITC calc.
Auto-resolution
Auto-segregate; reconcile TDS/TCS separately via GSTR-2X feed.
Customer prompt
(none - auto-segregated)
Audit-trail fields
tds_amounttcs_amountgstr_2x_period
Reference
CGST Section 51 + Section 52.
Part 2 · IMS PRD (one-pager)

Finkraft IMS - bulk actions, dry-runs, deemed-acceptance defense.

The user, the problem, the metrics, the workflow, the bulk-action UX for 100K+ invoices, edge cases, the GSTN/Cygnet integration model, and an explicit V1 vs cut list with reasoning.

User · problem

Primary
Enterprise tax operator - finance team member at a 50K-1M invoice/month enterprise (BFSI, IT services, pharma, manufacturing)
Secondary
Finance manager - needs filing-readiness visibility and exception escalation
Tertiary
Auditor - needs immutable trail of every state transition
Problem

Without product support, IMS at 100K invoices/month is a 30-person spreadsheet operation. Operators miss the 14th-day lock, deemed-acceptance silently inflates ITC, disputed invoices accept by inaction, and audit defense becomes archaeology.

Success metrics

Deemed-acceptance rate (unintentional)
Target
< 0.5% of pending volume
Baseline
TBD from current customer ops
Bulk-action throughput
Target
10K invoices / operator / hour
Baseline
300/hr manual
Time to clear monthly IMS queue
Target
< 4 hours per legal entity
Baseline
2-3 days
Audit-trail completeness
Target
100% of state transitions logged with actor + rule
Baseline
N/A - new capability

Workflow

  1. 1Invoice arrives in 2B feed → IMS state = pending
  2. 2Recon engine attaches mismatch tags (if any) + auto-suggested action
  3. 3Operator filters by mismatch category / supplier / amount band
  4. 4Bulk select → dry-run preview (shows N invoices changing, ₹X ITC delta)
  5. 5Confirm → state transitions atomically + audit log writes
  6. 6T-3 days from 14th: alert on any remaining pending volume
  7. 7After 14th: 2B locks → deemed-accepted invoices flow into ITC

Bulk-action UX

Pattern: Filter-then-bulk, never select-then-action.

  • Virtualized table (react-window / @tanstack/react-table) handling 100K rows
  • Multi-field filter sidebar - supplier, amount band, mismatch category, days-to-lock
  • Sticky bulk-action bar appears when ≥1 row selected: Accept · Reject · Mark Pending · Mark for Review
  • Dry-run modal: 'You're about to ACCEPT 8,432 invoices totaling ₹4.2cr in ITC. 124 invoices have unresolved mismatches - proceed anyway?'
  • Undo window: 15 minutes from commit, single click reverts entire batch
  • Async commit with progress bar for batches > 1K rows; partial-failure retry queue

Edge cases

  • Deemed acceptance: T-3 days alert + lock-window override prevention
  • Late filings: invoice that appears in subsequent 2B is treated as fresh pending, with link to prior-period attempt
  • Amendments: amendment auto-resets state to pending + surfaces side-by-side diff
  • Cross-GSTIN suppliers: same trade name, different GSTINs - group view with per-GSTIN bulk actions
  • Concurrent edits: optimistic locking with last-writer-wins + audit-trail conflict marker

Integration with GSTN + Cygnet

Cygnet APIs we'd consume
  • POST /ims/fetch-pending - pulls invoices in 'pending' state for a given GSTIN + period
  • POST /ims/action - atomic state transition (accept/reject/pending), idempotency-key required
  • GET /ims/audit-trail - read-back of state history per invoice (truth source)
Fallback
Multi-GSP - if Cygnet times out (> 8s p99), fail over to IRIS for the same action with idempotency key reuse
Rate limits
~500 actions/sec at Cygnet; batch upstream to fit
Reconciliation
Nightly cross-check: our IMS-actions table vs Cygnet read-back; surface drift in admin dashboard

V1 ship vs explicit cut list

V1 ship
  • Pending queue with mismatch tags
  • Bulk accept / reject / pending (dry-run + commit + undo)
  • Single-Cygnet integration
  • Deemed-acceptance T-3 alert
  • Audit log
Cut · with reasoning
  • Multi-GSP failover (V1.1 - add after measuring Cygnet uptime)
  • Operator workload heatmap (V2 - needs 6 weeks of operator data)
  • Amendment side-by-side diff UI (V1.1 - V1 ships a simpler 'amended' banner)
  • Cross-GSTIN supplier grouping (V2 - current customers are mostly single-entity)
Part 3 · Reconciliation matching algorithm

A 7-tier cascade with confidence scoring and operator-banded review.

Each tier is a strict superset of the previous in expense; if a cheaper tier matches, stop. Confidence drops as we relax constraints. Below 60% - mandatory operator review. Engineers can read the pseudo-code; auditors can read the rule strings.

Tier 1
100%
Exact
GSTIN == GSTIN AND invoice_no == invoice_no AND amount == amount
Auto-accept
Tier 2
95%
Normalized
Same as exact, after strip-lowercase-pad invoice_no normalization on both sides
Auto-accept
Tier 3
90%
FY-aware
Normalized + FY-token substitution (FY24-25 ↔ 2024-25 ↔ 24-25-FY)
Auto-accept
Tier 4
85%
Tolerance
Normalized GSTIN + invoice_no, amount within max(₹1, 0.01%), date within ±7 days
Auto-accept; sample-audit 10%
Tier 5
70%
Multi-month
Tolerance match against any 2B period within ±3 months from PR period
Surface for operator review
Tier 6
60%
Fuzzy-GSTIN
Levenshtein(GSTIN_pr, GSTIN_2b) ≤ 1 AND same PAN segment AND invoice_no + amount match
Mandatory operator review
Tier 7
0%
Unmatched
Nothing above fires
Surface for operator: chase supplier or write off
TypeScript-flavored pseudo-code
function match(prInvoice: InvoicePR, candidates2B: Invoice2B[]): MatchResult {
  // Tier 1 - Exact
  const exact = candidates2B.find(c =>
    c.supplier_gstin === prInvoice.supplier_gstin &&
    c.invoice_no === prInvoice.invoice_no &&
    c.invoice_amount === prInvoice.invoice_amount
  );
  if (exact) return { type: 'exact', confidence: 100, matched: exact };

  // Tier 2 - Normalized invoice_no
  const norm = normalize(prInvoice.invoice_no);   // lowercase + strip non-alphanumeric
  const normMatch = candidates2B.find(c =>
    c.supplier_gstin === prInvoice.supplier_gstin &&
    normalize(c.invoice_no) === norm &&
    c.invoice_amount === prInvoice.invoice_amount
  );
  if (normMatch) return { type: 'normalized', confidence: 95, matched: normMatch };

  // Tier 3 - FY-token substitution
  for (const variant of fyVariants(prInvoice.invoice_no)) {
    const m = candidates2B.find(c =>
      c.supplier_gstin === prInvoice.supplier_gstin &&
      normalize(c.invoice_no) === normalize(variant) &&
      c.invoice_amount === prInvoice.invoice_amount
    );
    if (m) return { type: 'fy_aware', confidence: 90, matched: m };
  }

  // Tier 4 - Tolerance bands
  const tolerance = candidates2B.find(c =>
    c.supplier_gstin === prInvoice.supplier_gstin &&
    normalize(c.invoice_no) === norm &&
    abs(c.invoice_amount - prInvoice.invoice_amount) <= max(1, 0.0001 * max(c.invoice_amount, prInvoice.invoice_amount)) &&
    abs(daysBetween(c.invoice_date, prInvoice.invoice_date)) <= 7
  );
  if (tolerance) {
    const categories = detectMismatchCategories(prInvoice, tolerance);
    return { type: 'tolerance', confidence: 85, matched: tolerance, mismatchCategories: categories };
  }

  // Tier 5 - Multi-month lookback
  const multiMonth = findInPeriodWindow(prInvoice, candidates2B, { months: 3 });
  if (multiMonth) return { type: 'multi_month', confidence: 70, matched: multiMonth };

  // Tier 6 - Fuzzy GSTIN (last resort before unmatched)
  const fuzzy = candidates2B.find(c =>
    samePAN(c.supplier_gstin, prInvoice.supplier_gstin) &&
    levenshtein(c.supplier_gstin, prInvoice.supplier_gstin) <= 1 &&
    normalize(c.invoice_no) === norm
  );
  if (fuzzy) return { type: 'fuzzy_gstin', confidence: 60, matched: fuzzy };

  return { type: 'unmatched', confidence: 0, matched: null };
}

Operator review UX at scale

  • Confidence-banded queues: ≥95% (sample-audit-only), 85-94% (review batch on Friday), 70-84% (review weekly), <70% (mandatory individual review)
  • Bulk-approve high-confidence: 'Approve all 14,832 normalized matches' - single confirm
  • Side-by-side mismatch view for tolerance / multi-month tier - left = PR, right = 2B, deltas highlighted
  • 'Why did this score 70%?' - inline rule trace shows which checks fired and which fell back
  • Bulk-chase supplier: select N unmatched, generate templated email with invoice list
Part 4 · AI-powered GST knowledge base

A RAG architecture with strict citations and calibrated humility.

The information architecture, content sources, per-persona usage, the six guardrails that keep this from hallucinating tax law, and the six-month metrics that prove it earned its keep.

Information architecture - pipeline

1Sources
CBIC circulars + notifications + instructions; GSTN advisories; CGST/IGST/UTGST Acts + Rules; key court rulings (AAR / High Court / SC); Finkraft internal SOPs; customer-resolved scenarios
2Ingestion
Weekly cron-pull from CBIC public listing; webhook from internal SOP repo; manual paste for one-off scenarios via /admin/kb/ingest
3Chunking
Semantic chunking (500-800 token windows, 100-token overlap, section-aware splits - preserve clauses and circular paragraphs)
4Embeddings
text-embedding-3-large (1536-dim) - Indian-English heavy, regulatory vocabulary; OpenAI directly or via OpenRouter
5Vector store
pgvector on Supabase - co-located with operational data; eliminates a cross-system query for citation back-pointers
6Retrieval
Hybrid retrieval - vector top-20 + BM25 keyword filter on circular/section refs; re-rank with cross-encoder; final top-5 to LLM
7Generation
Claude Sonnet 4.5 (default) with strict-citation system prompt; temperature 0.2; structured output (answer + citations[] + confidence + needs_review)
8Surface
Streaming chat UI + per-claim citation chips; 'strict mode' toggle for legal-interpretation questions

Content sources

SourceOwnerCadenceVolumeAuthority
CBIC circularsCBICweekly~150/yearinterpretive
CBIC notificationsCBICweekly~80/yearbinding
CBIC instructionsCBICad-hoc~40/yearinternal
GSTN portal advisoriesGSTNad-hoc~100/yearoperational
CGST/IGST/UTGST ActsParliamentrare~150 sectionsbinding
GST RulesGovtad-hoc~170 rulesbinding
AAR / Court rulingsJudiciaryweekly~500/yearprecedential
Finkraft SOPsInternalweekly~100operational
Customer scenario libraryInternaldailygrowingexperiential

Per-persona use cases

Sales
'Can we handle X enterprise's ITC scenario?' - pre-call confidence check
Reduces 'check with PM' loops by 70%
BA
'What's the right Cygnet payload for an amendment-of-amendment scenario?' - integration scoping
Integration-design cycles drop 1 week → 2 days
Customer
'Why did my March 2B miss invoice #12?' - self-serve from in-app help
Tier-1 support tickets ↓ 40%
Product
'Has any customer hit this RCM amendment before?' - pattern recognition + roadmap input
Time to detect a systemic issue: 2 weeks → 2 days
Internal compliance
'What changed in the latest CBIC circular and what's our exposure?' - regulatory tracking
48-hour SLA from publication to product-impact assessment

Hallucination guardrails

Source-attribution-required
No claim ships without ≥1 citation. System prompt enforces 'Every factual statement must reference [N]'. Post-generation regex strips any sentence lacking [N] and surfaces a 'partial answer' badge instead.
Confidence scoring
Retrieval similarity score (top-1) → confidence label. High (≥0.75), Medium (0.55-0.74), Low (<0.55). Displayed as a pill next to the answer.
Strict mode
Toggle for legal-interpretation questions. If max retrieval score < 0.55, refuse with: 'No source I have strongly supports this. Closest reference: [X]. A practitioner should review.' Never invent.
Refusal guardrail
Hard refusal on: binding tax-filing advice for a specific entity, litigation defense recommendations, individual rate-applicability decisions. Surface scope-guard message + redirect.
Eval set + regression tests
100+ ground-truth Q→A pairs (from CBIC FAQs + customer-resolved scenarios). Re-run on every prompt change, every model change, every weekly corpus refresh. Block deploys on accuracy regression > 3pp.
Audit log
Every query + retrieved chunks + LLM response + user feedback persisted. Enables post-hoc 'why did the KB say X?' investigations when an answer turns out wrong.

Six-month success metrics

Query volume
200+/day across Sales+BA in month 3
Adoption proxy
Citation accuracy
≥ 95% of cited [N] references map to a real chunk
Hallucination defense
Factual accuracy (eval set)
≥ 90% on 100-Q ground-truth set
Quality bar
P50 / P95 latency
1.5s / 4s
Conversational UX
Time-to-update post-circular
< 48 hours from CBIC publication
Regulatory currency
Sales / BA daily active usage
60% of team weekly active in month 6
Workflow integration
Tier-1 support deflection
40% of common GST queries self-served via KB
ROI
Strict-mode refusal rate
5-15% on legal-interpretation Qs (not 0%, not 30%)
Calibrated humility
Closing

The KB is only as good as its refusal rate. A knowledge base that answers everything confidently is a liability dressed as a feature. The win condition is: Sales calls it before chasing PM, BAs design integrations from cited evidence, customers self-serve common GST questions, and when the right answer doesn't exist in the corpus - the system says so, cites the closest reference, and tells the user a practitioner should review.

One more thing

The four parts above describe a product. The next tab - Product - is that product, running on seeded synthetic data. The recon engine implements the 7-tier cascade. The IMS workspace implements the bulk-action UX. The knowledge base runs the RAG pipeline with the guardrails described. Reading is half of it. Using it is the other half.

↑ Independent educational project by Kaushal Khodifad. Finkraft.ai is a real company in the enterprise GST compliance and reconciliation space; this design and the underlying prototype were built by Kaushal as a portfolio study. Not affiliated with, endorsed by, or representative of Finkraft.ai's actual product. Data is from public sources. Figures are estimates.

Return to portfolioOpen the live demo