Skip to content

Releases: yigitcan-ozturk/bidlint

bidlint v1.1.0

Choose a tag to compare

@github-actions github-actions released this 22 Aug 16:20
df5b66b

bidlint v1.1.0

BidLint 1.1.0 completes the production-adoption milestone while preserving the frozen BidLint 1.x compliance semantics.

Production-adoption controls

  • offline BidLint 1.x report conformance validation and compatibility manifest
  • private-first external-pilot workspace and evidence-retention protocol
  • non-leaking pilot sanitization scanner for contact, commercial, metadata, hidden-content and XLSX leakage signals
  • manifest-driven repeated pilot execution with deterministic output and corpus SHA-256 evidence
  • immutable approved-baseline replay verification with bidlint-pilot-verify
  • explicit bidlint-pilot-gate requiring clean sanitization, deliberate human/domain approval, reviewed non-PASS findings, manual specification-scope disposition when required, zero unresolved limitations and exact baseline replay
  • conservative XLSX specification requirement blocks with independent worksheet selection and explicit unscoped-row coverage evidence
  • production-shaped conflict-path CPU and peak-memory profiling gate
  • validated wheel artifact retention for isolated private-pilot replay
  • fail-closed stable-release workflow that refuses stale or premature tags pointing at a different release commit

Correctness hardening derived from the external pilot

  • empty external pilots cannot pass with zero evaluated requirements
  • Grade/designation values such as Grade 304 and A15 stay qualitative rather than becoming accidental numeric thresholds
  • composite dimensions remain qualitative until deterministic multidimensional comparison is supported
  • standard OOXML schema URLs no longer create sanitization URL false positives
  • unrelated fuzzy parameter names without lexical overlap require stronger evidence before matching
  • commercial XLSX values hidden behind currency number formats are detected by the sanitization scanner
  • structured XLSX rows outside the supported contiguous requirement block are surfaced as explicit manual-scope evidence rather than silently treated as covered

External sanitized pilot gate

Issue #39 completed the release-evidence gate using a real external drainage-schedule-derived private sanitized corpus.

Final approved replay evidence:

  • reviewer: yigitcan-ozturk
  • review date: 2026-08-22
  • decision: APPROVE_BASELINE
  • sanitization: automated_clear=true, 0 blockers, 0 review findings
  • evaluated requirements: 6
  • findings: 5 REVIEW, 1 MISSING, 0 PASS, 0 DEVIATION
  • deterministic: true
  • conformant: true
  • manual XLSX scope: 35 unscoped populated rows (header + 34 item rows), explicitly human-reviewed
  • false positives: 0
  • false negatives: 0
  • unresolved limitations: 0
  • known product defects: 0
  • approved baseline replay: exact match, 0 mismatches
  • final gate: release_ready=true, failure_count=0

Final reconstructed private evidence digests:

  • manifest SHA-256: 68f165a2f2a27df5ba927e52f098c743b2687f8321d8fda252569ebd195dc97f
  • corpus SHA-256: 93d5738fb2f5b660e940c5a2843bf40416e09c2f5480a735b048455152541e18
  • baseline/replay output SHA-256: 759e2b510a2dd6629f23874f656fd301fafb0201b30f15cdd1cd85ae7b6f2084

Raw external/customer documents and the private approval/evidence workspace are not committed to the public repository.

Compatibility boundary

This release does not change the frozen BidLint 1.x PASS / DEVIATION / MISSING / REVIEW semantics or deterministic scoring contract. BidLint does not perform commercial scoring, contractual acceptance or inferred knockout acceptance. External-pilot approval is software baseline/release evidence, not supplier compliance acceptance.

Validation required before merge

The release PR must pass:

  • Ruff and pytest on Python 3.11, 3.12 and 3.13
  • wheel/sdist build, twine check, installed CLI smoke and pip check
  • runtime dependency audit
  • deterministic 20k-fact benchmark
  • production-shaped conflict-path CPU and peak-memory profile

The stable v1.1.0 tag and GitHub Release must only be created from the final merged release commit. The stale/premature v1.1.0 release and tag from the invalidated earlier release sequence were removed before this release branch was prepared.

bidlint v1.0.0

Choose a tag to compare

@github-actions github-actions released this 21 Aug 03:12
b1bcfd1

bidlint v1.0.0

Released 2026-08-21.

BidLint 1.0.0 is the first stable-contract release of the deterministic technical bid compliance engine.

Stable compatibility contract

The 1.x line now has an explicit compatibility floor covering:

  • public CLI commands and process exit codes;
  • report JSON required keys;
  • SourceRef, Requirement, VendorFact, and Finding required fields;
  • PASS / DEVIATION / MISSING / REVIEW finding semantics;
  • knockout status semantics;
  • deterministic compliance-score behavior;
  • semantic-versioning and backward-compatibility policy.

The machine-readable contract is available through bidlint.contracts.stable_contract_manifest() and is protected by regression tests.

Procurement workflow

The stable release includes the v0.8 procurement workflow:

  • explicit technical knockout criteria;
  • bidder clarification and unanswered requirement registers;
  • deviation and internal review queues;
  • procurement-ready ranking;
  • procurement-aware supplier-scorecard contract v2.

No commercial scoring, price preference, contractual acceptance, or implicit knockout inference is introduced.

Production hardening

The v0.9 hardening work is included in 1.0.0:

  • stable CLI error categories and exit codes;
  • malformed/adversarial PDF, XLSX, and IFC regression coverage;
  • wheel/sdist build and smoke-install validation on Python 3.11, 3.12, and 3.13;
  • runtime dependency security audit;
  • deterministic large-package benchmark with repeated output-digest verification.

The CI benchmark exercises 20,000 input facts and requires deterministic consolidation output under a deliberately broad regression ceiling.

Compatibility

BidLint 1.0.0 supports Python 3.11, 3.12, and 3.13.

Within the 1.x line, patch releases are intended for compatible fixes and minor releases may add backward-compatible surfaces. Removing, renaming, or semantically repurposing frozen contract elements requires a new major version.

See docs/STABLE_CONTRACT.md for the full compatibility policy.

bidlint v0.7.0

Choose a tag to compare

@github-actions github-actions released this 20 Aug 17:29
15fbdc0

bidlint v0.7.0

Released: 2026-08-20

v0.7.0 moves bidlint from single vendor-document comparison toward deterministic real-world bid intake. A supplier submission can now be treated as a multi-document evidence package while preserving the existing rule that uncertainty, source disagreement and hidden precedence must never become automatic technical decisions.

Highlights

Multi-document vendor packages

A vendor input may be a directory containing supported direct-child PDF, XLSX and explicitly scoped IFC evidence:

Supplier-A/
├── compliance-schedule.xlsx
├── pump-datasheet.pdf
├── technical-offer.pdf
└── model.ifc

The package enters the same VendorFact and deterministic compliance pipeline used by direct vendor files.

Equivalent facts across documents collapse deterministically, including compatible engineering-unit conversions. Conflicting evidence is preserved as an explicit provenance-rich REVIEW condition instead of choosing a source silently.

Explicit document classification

Every direct-child package file is assigned a visible document class:

  • specification
  • datasheet
  • compliance-schedule
  • technical-offer
  • ignored

Classification uses deterministic filename rules plus exact programmatic overrides. Copied employer specifications and ignored/commercial material do not become vendor technical evidence.

Unsupported file types remain visible as ignored package documents rather than being parsed or guessed.

Explicit evidence priority

Packages may opt into an ordered evidence-priority policy across technical document classes.

package = parse_vendor_package(
    "Supplier-A",
    evidence_priority=(
        "compliance-schedule",
        "technical-offer",
        "datasheet",
    ),
)

No priority exists by default. Without an explicit policy, conflicting facts continue to produce REVIEW.

Priority only narrows a parameter group to the highest available configured class. It never breaks a disagreement between two documents in the same highest-priority class; those conflicts still require review.

Project terminology aliases participate in consolidation

The existing project-specific alias mapping now applies before package duplicate/conflict consolidation as well as during requirement matching.

{
  "supplier rated output": "motor power"
}

This allows vendor-specific nomenclature in different package documents to resolve to the same canonical parameter before evidence consistency is evaluated.

Aliases do not introduce fuzzy grouping, hidden source precedence or additional confidence.

Mixed-package ranking selector scoping

rank can mix direct files and package directories while using IFC/XLSX selector options.

Selector validation looks inside package directories only at evidence-classified files. IFC selectors are applied only to direct IFC inputs and packages containing evidence IFC files; --xlsx-sheet is applied only to direct XLSX inputs and packages containing evidence XLSX files.

This prevents a global selector from invalidating unrelated PDF-only suppliers in the same ranking run.

Package-level evidence audit

VendorPackage.evidence_audit records how every parsed technical fact was treated during consolidation.

Each audit entry preserves:

  • canonical parameter
  • original VendorFact and provenance
  • document class
  • disposition: selected, equivalent-duplicate, conflict or lower-priority
  • explicit priority rank when applicable

VendorPackage.to_audit_dict() exposes a JSON-ready package audit containing document classifications, ignored documents, priority policy, raw evidence dispositions, consolidated facts and conflict facts.

The evaluator contract remains unchanged; the audit surface adds traceability rather than a second decision engine.

Sanitized regression packages

The release includes generated multi-document regression fixtures for five engineering families:

  • pump: alias-aware equivalent evidence across PDF/XLSX documents
  • motor: explicit compliance-schedule priority over conflicting lower-priority evidence
  • valve: unresolved disagreement inside the same highest-priority class
  • HVAC: aliasing, engineering-unit conversion, copied-specification exclusion and ignored commercial material
  • electrical: equivalent evidence alongside an unprioritized technical conflict

Fixtures are synthetic and vendor-neutral. Tests generate temporary PDF and formula-free XLSX files and run the normal parsers rather than replacing extraction with mocks.

Existing safety boundaries remain in force

v0.7.0 does not weaken earlier input constraints:

  • XLSX formulas, VBA/macros, external relationships, hidden evidence worksheets, merged cells and ambiguous layouts remain rejected
  • IFC evidence still requires explicit element scope through the existing IFC selection rules
  • unsupported package files are not interpreted as technical evidence
  • copied specification documents are not allowed to satisfy vendor requirements
  • file type alone never establishes authority
  • source disagreement never becomes an automatic PASS or DEVIATION

Validation

The v0.7 branch is covered by GitHub Actions on Python 3.11, 3.12 and 3.13 with Ruff and pytest, including regression coverage for:

  • deterministic package discovery
  • document classification and overrides
  • unit-aware equivalent evidence consolidation
  • conflict-to-REVIEW behavior
  • explicit evidence-priority policy and same-class tie handling
  • project alias threading through CLI package intake
  • mixed PDF/XLSX/IFC package selector scoping
  • package-level evidence audit dispositions and provenance
  • generated pump, motor, valve, HVAC and electrical multi-document packages

Deliberate limits

This release keeps package intake intentionally conservative:

  • only direct-child package documents are considered
  • document-class overrides are currently a programmatic surface rather than a package manifest or dedicated CLI policy file
  • evidence priority is explicit and opt-in; no hidden default hierarchy is inferred
  • package intake does not add commercial or price scoring
  • the deterministic requirement matcher and compliance evaluator remain authoritative

v0.7.0 keeps the project rule unchanged: evidence before confidence.

bidlint v0.6.0

Choose a tag to compare

@github-actions github-actions released this 20 Aug 12:45
a8b76bc

bidlint v0.6.0

Released: 2026-08-20

v0.6.0 adds deterministic XLSX vendor-input support to the existing technical-compliance engine. Explicit spreadsheet offer tables can now enter the same VendorFact model used by PDF and IFC evidence without adding a spreadsheet runtime dependency or weakening the evidence-first boundary.

Highlights

XLSX vendor inputs

A formula-free vendor offer workbook can now be compared directly with a specification:

bidlint compare specification.pdf supplier-offer.xlsx

The selected worksheet must expose one explicit parameter column and one explicit offered-value column. Unit and section columns are optional.

For workbooks with more than one visible worksheet, select the evidence sheet explicitly:

bidlint compare specification.pdf supplier-offer.xlsx \
  --xlsx-sheet "Technical Offer"

The same XLSX adapter is available through extract and rank.

bidlint extract supplier-offer.xlsx --kind vendor \
  --xlsx-sheet "Technical Offer"

Mixed vendor ranking can combine supported PDF, XLSX and explicitly scoped IFC inputs:

bidlint rank specification.pdf vendor-a.pdf vendor-b.xlsx vendor-c.ifc \
  --xlsx-sheet "Technical Offer" \
  --ifc-guid 1AbCdEfGhIjKlMnOpQrStu

Evidence provenance

Every accepted spreadsheet row becomes a normal VendorFact and preserves:

  • workbook filename
  • worksheet row number
  • selected worksheet name
  • optional row section/category/system context

A source section can therefore identify evidence such as:

XLSX:Technical Offer/Electrical

After extraction, the existing terminology matcher, engineering-unit conversion and deterministic compliance evaluator remain authoritative.

Spreadsheet safety boundary

The workbook is treated as evidence, not executable logic.

v0.6.0 deliberately rejects structures that would require calculation, hidden state or positional guessing:

  • formulas
  • VBA/macros
  • external workbook relationships
  • hidden evidence worksheets
  • merged cells in the selected worksheet
  • multiple visible worksheets without explicit --xlsx-sheet selection
  • duplicate or ambiguous parameter/offered headers
  • incomplete evidence rows containing only a parameter or only an offered value
  • conflicting units between the offered cell and an explicit unit column

Boolean cells remain qualitative TRUE / FALSE evidence rather than being converted into numeric 1 / 0 compliance values.

The parser does not recalculate workbooks, follow links, unhide worksheets or reconstruct merged spreadsheet layouts.

Dependency model

XLSX input is parsed directly from OOXML using the Python standard library.

The standard installation remains:

pip install bidlint

No Excel, LibreOffice, openpyxl or other spreadsheet runtime is required for XLSX input or existing XLSX technical-bid output.

Optional integrations remain separate:

pip install 'bidlint[ifc]'
pip install 'bidlint[mcp]'

Existing deterministic core remains authoritative

Specification PDF ──> Requirement ───────────────────────────────┐
                                                                │
Vendor PDF ─────────> VendorFact ────────────────────────────────┤
Vendor XLSX ────────> explicit OOXML adapter ─────> VendorFact ─┤
Selected IFC ───────> property adapter ───────────> VendorFact ─┤
                                                                ▼
                                                     terminology matcher
                                                                │
                                                                ▼
                                                      unit-aware evaluator
                                                                │
                                                                ▼
                                           PASS / DEVIATION / MISSING / REVIEW

XLSX support adds a new evidence adapter, not a new decision engine.

Validation

The stable release is covered by GitHub Actions on Python 3.11, 3.12 and 3.13, including regression coverage for:

  • explicit header discovery
  • visible worksheet selection
  • row and section provenance
  • numeric and qualitative values
  • boolean preservation
  • explicit engineering units
  • formula rejection
  • macro and external-link rejection
  • merged-cell rejection
  • ambiguous worksheet/header rejection
  • CLI extract, compare and rank dispatch
  • coexistence with existing PDF and IFC workflows

Deliberate limits

This release does not:

  • infer spreadsheet formulas
  • execute spreadsheet code
  • follow external workbook links
  • guess hidden evidence
  • reconstruct merged worksheets
  • choose among multiple visible evidence sheets without an explicit selection
  • replace the existing deterministic matcher or evaluator
  • add commercial or price scoring to bidlint

v0.6.0 keeps the project rule unchanged: evidence before confidence.

bidlint v0.5.0

Choose a tag to compare

@github-actions github-actions released this 20 Aug 04:55
cfe2d24

bidlint v0.5.0

Released: 2026-08-20

v0.5.0 completes the engineering-ecosystem milestone around the deterministic compliance core. It adds explicitly scoped IFC vendor-property inputs, a safe technical-compliance hand-off to supplier-scorecard, and native .xlsx technical bid tabulation.

Highlights

IFC property inputs

Vendor evidence can now come from a local IFC file as well as a PDF.

IFC support is optional:

pip install -e '.[ifc]'

Select one vendor element explicitly by GlobalId:

bidlint compare specification.pdf equipment.ifc \
  --ifc-guid 1AbCdEfGhIjKlMnOpQrStu

Or use an IFC class when the class resolves to exactly one element:

bidlint extract equipment.ifc --kind vendor \
  --ifc-class IfcPump \
  --ifc-pset Pset_PumpCommon

Selected scalar property-set values become ordinary VendorFact records and then flow through the existing terminology matcher, unit conversion and deterministic evaluator.

Safety rules include:

  • IFC scope is mandatory
  • multi-element class selections are rejected instead of mixed
  • complex/list values are skipped
  • geometry is not evaluated
  • scalar numeric primitives remain unitless unless the source value explicitly includes a unit
  • provenance is preserved as IfcClass:GlobalId/Pset

See docs/IFC.md.

supplier-scorecard technical-compliance contract

A single-vendor comparison can emit a versioned JSON hand-off for the companion supplier-scorecard project:

bidlint compare specification.pdf vendor-a.pdf \
  --supplier-name "Supplier A" \
  --scorecard-output supplier-a-technical.json

When every finding is deterministically resolved as PASS, DEVIATION or MISSING, the fragment includes bidlint's existing 0–100 compliance score as technical_compliance.

If any finding remains REVIEW, the integration deliberately emits:

{
  "technical_compliance": null,
  "technical_compliance_status": "REVIEW_REQUIRED"
}

This prevents an incomplete technical review from becoming a misleading procurement ranking input. The detailed bidlint report remains the authoritative technical audit.

See docs/SUPPLIER_SCORECARD.md.

Excel technical bid tabulation

Multi-vendor ranking now supports native .xlsx output:

bidlint rank specification.pdf vendor-a.pdf vendor-b.pdf \
  --output technical-tabulation.xlsx

The workbook contains:

  • Ranking — vendor order, compliance scores and status counts
  • Matrix — requirement-by-vendor review matrix with status-specific fills
  • Audit — long-form evidence, confidence, source page/section and deterministic reason

The workbook uses frozen panes, autofilters, wrapped text and fixed readable widths. It contains no formulas, macros or external links.

The OOXML package is generated with the Python standard library, so the base package gains no spreadsheet runtime dependency. Fixed ZIP timestamps also make identical report data and bidlint version produce byte-identical workbook output.

See docs/WORKBOOK_EXPORT.md.

Existing deterministic core remains authoritative

v0.5.0 does not create new decision engines for IFC, procurement integration or spreadsheets.

PDF / selected IFC property evidence
              │
              ▼
      Requirement / VendorFact
              │
              ▼
       terminology matcher
              │
              ▼
        unit-aware evaluator
              │
              ▼
PASS / DEVIATION / MISSING / REVIEW
              │
      ┌───────┼───────────┐
      ▼       ▼           ▼
 JSON/HTML  XLSX      supplier-scorecard

The ecosystem adapters consume deterministic results; they do not override them.

Dependency model

The standard installation remains lightweight:

pip install bidlint

Optional integrations remain separate:

pip install 'bidlint[mcp]'
pip install 'bidlint[ifc]'

XLSX export requires no additional package.

Validation

The release is covered by the existing Python 3.11, 3.12 and 3.13 CI matrix plus regression tests for:

  • IFC scalar extraction, ambiguity rejection and provenance
  • PDF/IFC deterministic comparison
  • supplier-scorecard READY / REVIEW_REQUIRED / NO_REQUIREMENTS contracts
  • CLI integration output behavior
  • OOXML package structure and worksheet ordering
  • XLSX ranking, matrix and audit evidence
  • deterministic workbook bytes
  • rank --output .xlsx

Deliberate limits

This release does not:

  • perform IFC geometry compliance
  • guess which of multiple IFC elements represents a vendor offer
  • infer engineering units missing from IFC values
  • turn REVIEW into a procurement score
  • add commercial or price logic to bidlint
  • hide workbook calculations in formulas
  • change the existing deterministic ranking order

v0.5.0 completes the published roadmap while preserving the core rule: evidence before confidence.

bidlint v0.4.0

Choose a tag to compare

@github-actions github-actions released this 20 Aug 03:52
a7d4033

bidlint v0.4.0

Released: 2026-08-20

v0.4.0 exposes the deterministic bidlint core through an optional local MCP server and adds a persistent, pollable job lifecycle for larger document operations.

Highlights

Local MCP server

Install the optional MCP integration with:

pip install -e '.[mcp]'

Run the stdio server with:

bidlint-mcp

The synchronous MCP tool surface includes:

  • extract
  • compare
  • explain

These tools call the same deterministic PDF parsers, terminology matcher, engineering-unit conversion and compliance evaluator used by the CLI.

Filesystem sandbox

MCP document and alias paths are constrained to BIDLINT_MCP_ROOT, or to the server working directory when the variable is not set.

The server rejects:

  • parent traversal outside the configured root
  • absolute paths outside the root
  • symlinks that resolve outside the root
  • unexpected document/alias file types

The MCP server does not fetch remote URLs.

Pollable long-running jobs

Large extraction/comparison work can be submitted through:

  • submit_extract
  • submit_compare

and inspected through:

  • job_status
  • job_result
  • cancel_job

Job records and terminal results are stored atomically under:

<BIDLINT_MCP_ROOT>/.bidlint/jobs

The in-process worker pool defaults to two workers and can be configured from 1 to 8 with BIDLINT_MCP_JOB_WORKERS.

Running jobs use cooperative cancellation. If the server process stops, previously queued/running jobs are not silently resumed; they are marked failed with an explicit restart error when the job manager starts again.

MCP Tasks-extension boundary

The job lifecycle is deliberately implemented as explicit bidlint tools rather than claiming native MCP Tasks support before the Python MCP SDK exposes a supported server API for that extension.

The internal job manager is kept separate from the MCP adapter so a future native Tasks integration can reuse the same deterministic lifecycle and persistence model.

No second decision engine

MCP does not add another compliance authority. Clients cannot supply a status and have bidlint trust it.

Both synchronous and queued MCP paths still produce PASS / DEVIATION / MISSING / REVIEW through the existing deterministic evaluation layer.

Safety boundary

v0.4.0 deliberately does not:

  • expose a network/HTTP server by default
  • fetch remote documents
  • bypass BIDLINT_MCP_ROOT
  • force-terminate a running parser thread
  • silently resume interrupted work after restart
  • claim native MCP Tasks-extension compatibility through a custom wire-protocol implementation
  • change the deterministic compliance rules established by previous releases

See docs/MCP.md for setup, tool contracts and lifecycle details.

bidlint v0.3.0

Choose a tag to compare

@github-actions github-actions released this 20 Aug 03:27
2df5b7b

bidlint v0.3.0

Released: 2026-08-20

v0.3.0 adds a provider-neutral boundary for optional AI-assisted or external structured extraction while keeping the deterministic compliance engine authoritative.

Highlights

Replaceable extraction providers

Optional integrations can implement the StructuredExtractor protocol and return structured requirement or vendor-fact candidates. The core package does not depend on a specific model vendor, SDK, API key or network service.

Evidence before provider confidence

Every provider candidate must include confidence plus source evidence. Before a candidate can enter the deterministic core, bidlint verifies:

  • confidence is finite and within [0, 1]
  • confidence meets the configured minimum threshold
  • the declared source page exists
  • the evidence snippet actually occurs on that PDF page after whitespace normalization
  • the candidate type matches specification/vendor extraction
  • numeric requirement fields are structurally consistent

Rejected candidates remain outside compare() and are returned with explicit rejection reasons.

Deterministic evaluation remains authoritative

Provider confidence is extraction confidence only. It does not become the compliance confidence and it cannot emit PASS, DEVIATION, MISSING or REVIEW.

Validated candidates are converted to the existing Requirement and VendorFact models. The existing terminology matcher, engineering-unit conversion and deterministic evaluator then produce the final findings.

Provider contract

A provider implements:

class MyExtractor:
    name = "my-provider"

    def extract(self, document: Path, kind: ExtractionKind) -> ExtractionBatch:
        ...

Use extract_with_provider() to invoke and validate an adapter, or validate_extraction() when a structured batch is already available.

See docs/AI_EXTRACTION.md for the full contract.

No new runtime AI dependency

The standard installation still requires no LLM SDK and makes no automatic external AI calls. The deterministic PDF parser and all existing CLI workflows continue to work unchanged.

Safety boundary

v0.3.0 deliberately does not:

  • bundle a model/provider implementation
  • allow model output to set compliance status
  • treat high provider confidence as proof of engineering correctness
  • introduce model-defined comparison operators or unit rules
  • solve OCR/image interpretation automatically

This release establishes an auditable integration boundary for future optional providers without weakening the deterministic decision model.

bidlint v0.2.2

Choose a tag to compare

@github-actions github-actions released this 20 Aug 02:54
fc0f7c4

bidlint v0.2.2

Released: 2026-08-20

v0.2.2 hardens deterministic vendor-datasheet parsing for advanced but explicitly evidenced table layouts. The release expands document coverage without changing the core rule: ambiguous layout evidence is skipped instead of guessed.

Highlights

Coordinate-aligned sparse rows

Recognized tables can now recover rows whose intermediate cells are visually blank when the parameter and offered values align closely with explicit header anchors.

  • blank intermediate cells no longer shift the offered value into the wrong semantic column
  • blank Unit cells remain unitless
  • fragments near column boundaries are rejected rather than assigned by proximity alone

Explicit merged-cell geometry

The positioned-text pass also captures explicit axis-aligned PDF rectangle (re) geometry.

  • merged intermediate cells can be recognized when Parameter and Offered remain distinct cell boxes
  • text inside an intermediate merged cell is not split into fabricated Unit / Required values
  • merges touching Parameter or Offered are rejected
  • rotated/skewed rectangles and arbitrary line grids remain unsupported

Repeated explicit header groups

Side-by-side technical tables can now be parsed when each visual group repeats its own parameter-like and offered/value headers.

Parameter     Unit   Offered     Parameter        Unit   Offered
Motor power   kW     11          Flow rate        m3/h   125

Each complete row produces one fact per explicit group. Incomplete repeated rows are skipped as a whole rather than partially reconstructed.

Safer Item / Description tables

When a header contains both Item and Description before the offered/value column, Description is preferred as the parameter field because it is the nearest parameter-like header to the offered evidence.

Safety boundary

v0.2.2 still does not:

  • OCR scanned/image-only PDFs
  • infer arbitrary line-segment grids as table cells
  • split semantic values out of merged intermediate cells
  • guess multi-column group boundaries when explicit repeated headers are absent
  • accept coordinate fragments that fall too close to a column boundary

Validation

All changes are covered by synthetic positioned/boxed PDF regressions and the project CI matrix on Python 3.11, 3.12 and 3.13 with Ruff and pytest.

bidlint v0.2.1

Choose a tag to compare

@github-actions github-actions released this 20 Aug 02:00
b42872d

bidlint v0.2.1

Released: 2026-08-20

v0.2.1 hardens bidlint for more realistic engineering datasheets and larger multi-vendor review workflows while keeping the deterministic decision model conservative.

Highlights

Layout-aware vendor PDF parsing

  • preserves horizontal PDF layout for vendor datasheets
  • reconstructs explicit parameter/unit/required/offered tables
  • reads the offered column without confusing it with requirement/reference columns
  • supports two independent numeric parameter/value pairs on one visual row
  • supports a final offered value wrapped to the next numeric line
  • supports parameter labels continued by an explicit trailing hyphen
  • skips ambiguous multi-column rows rather than guessing

Broader deterministic unit conversion

The registry now covers:

  • power: W / kW / MW
  • voltage: mV / V / kV
  • current: mA / A / kA
  • frequency: Hz / kHz / MHz
  • apparent power: VA / kVA / MVA
  • pressure: Pa / kPa / MPa / mbar / bar / psi
  • length: mm / cm / m / km / in / ft
  • mass: g / kg / t
  • force: N / kN
  • flow: L/s / L/min / m³/s / m³/h
  • temperature: °C / °F / K

Dimension safety remains explicit. Real power is not treated as apparent power, voltage is not current, gauge/absolute pressure suffixes are not collapsed, and frequency is not converted into rotational speed.

Sanitized datasheet regression fixtures

Tests now render vendor-neutral motor, pump and valve layouts into temporary PDFs and verify:

  • multi-page source provenance
  • revision/metadata noise
  • explicit technical tables
  • side-by-side fields
  • wrapped table continuations

No third-party vendor PDF or confidential project data is embedded in these fixtures.

Batch comparison ergonomics

  • multi-vendor Markdown technical bid tabulation export
  • rank --top N for compact terminal display
  • full JSON / Markdown / HTML / CSV exports remain complete even when terminal output is limited

Safety boundaries

v0.2.1 deliberately does not claim arbitrary merged-cell reconstruction. Coordinate-aligned sparse cells and advanced ambiguous multi-column layouts remain scheduled for v0.2.2 so they can be implemented without positional guessing.

OCR also remains outside the deterministic parser.

Validation

The release branch must pass Ruff and pytest on Python 3.11, 3.12 and 3.13 before merge.

bidlint v0.2.0 — Real-World Engineering Bid Compliance

Choose a tag to compare

@yigitcan-ozturk yigitcan-ozturk released this 19 Aug 17:25
f2fada4

bidlint v0.2.0

Real-world engineering bid compliance. Evidence before confidence.

bidlint v0.2.0 expands the deterministic compliance core into a more practical technical bid evaluation workflow for engineering specifications, vendor datasheets, bids and submittals.

What's new

  • Deterministic engineering unit conversion for:
    • Power
    • Pressure
    • Length
    • Flow
  • Safer parsing of real-world vendor datasheets
  • Support for colon-delimited, two-column and paired-line technical fields
  • Conservative engineering terminology normalization
  • Project- and vendor-specific aliases with --aliases
  • Multi-vendor technical compliance ranking
  • Self-contained HTML technical bid tabulation
  • Requirement-by-vendor comparison matrix
  • CSV audit export for spreadsheet and procurement workflows
  • Improved traceability and explicit uncertainty handling

Engineering safety

bidlint only makes a deterministic compliance decision when the available evidence supports it.

Unknown units, missing evidence, ambiguous terminology or qualitative requirements remain:

REVIEW

rather than being converted into an artificial PASS or FAIL.

Evidence before confidence.

Example

Specification: Motor power shall be minimum 10 kW.
Vendor       : Motor power: 10000 W

PASS — Offered 10000w (= 10kw) satisfies >= 10kw.