Mise OS · the factory behind it
Agentic Software Factory · Port × Bright Data × SigNoz

An operating system for physical work, and the factory that builds it.

The app is the test run. The factory is the deliverable.

Mise OS routes physical work to whoever should execute it: an agent, a robot, or a human.

A real defect, not a synthetic one

Mise OS routes food between restaurant branches, and every routing decision is arithmetic over scraped menu and supplier data. The dataset it inherited was assembled by an earlier scraping pipeline (search, then a generic page scrape, then LLM extraction) which failed silently on prices and left a measurable hole.

menu.price_null_rate
56.25%
72 of 128 dish prices are null. Routing was running on data that is 56% blind, and nothing was watching. No contract, no metric, no alert.

The loop

Each tool does a job the other two cannot. Observability is not a dashboard bolted on at the end. An alert is what starts the factory.

SigNoz alert the sensor Port governance triage fix path human gate approve release brightdata scraper heal Bright Data repairs the feed re-verify null-rate under 5% detection is ours. The CLI never decides a scraper is broken.
Bright Data is not a garnish: the feed it scrapes is the thing that fails, and scraper heal is what fixes it.

SigNoz, the nerves

Traces every stage, endpoint and background job. Its alerts start the factory rather than merely reporting on it.

Port, the factory floor

Holds goals, decisions, risks and services. Records the plan and release gates, with a trace id on every entity.

Bright Data, the senses and the repair

The supplier feed is what breaks, and scraper heal is what mends it. Across 22 upstream status pages the collector's null-rate on overall_status was 63.16%. One healed selector took it to 26.32% with zero regressions on the four control sites.

Two entry points, one pipeline

So the factory demonstrably builds, not just repairs. Every stage is one OTel span under a single factory.run root, and one Port entity carrying that run's trace_id, so any node in the Port graph jumps straight to its trace. If it is not traced, it did not happen.

# a human asks
node factory/run.js --brief "Route the Downtown tomato shortage"

# a signal asks
node factory/run.js --incident data_source_broken

  brief → plan → build → verify → approve → release → audit
A run produces a real routing decision
Transfer 10kg, buy net 26kg @ $2.05 = $53.30
  • robottransfer, 10kg from Marina, expires in 2 days, use first
  • humanhandoff, crate handed to the cook at the service pass
  • agentprocure, only the net shortage is bought: 26kg at $2.05/kg

Surplus moves before anything is bought. A branch below its own par cannot donate. Nearest-expiry stock goes first. Only the net shortage reaches procurement.

You approve the rehearsal, not the diff

The app generates a simulation from the dispatch the factory just produced: this donor branch, this crate, this expiry window, this path, this handoff. A different shortage draws a different simulation. The human watches what the robot will do and approves that; the click writes approval_status back to Port.

node app/server.js        # http://localhost:3000
Falsifiable

Change the branch numbers in factory/mise.js, re-run the factory, reload. The simulation must show a different donor and quantity. If it does not, it is a hardcoded demo.

The rehearsal is what a human approves against. The same approved plan is what would deploy to a physical robot. The simulation is the gate, not a decoration.

The self-healing edge

The supplier page's prices stop being text inside .price and become an attribute on a renamed element, the kind of change a site redesign makes. GitHub Pages republishes, and the contract catches it.

./scripts/break-mirror.sh        # a real commit that restructures the price markup
node factory/run.js --incident data_source_broken
node factory/heal.js             # detect → human gate → repair → re-verify

supplier null-rate 100.0%  (threshold 5%) -> FAIL
failing fields: name, price
release SKIPPED (contract failed)

Detection is ours, not the CLI's. Bright Data never decides a scraper is broken. verify computes the null-rate, and heal.js passes the concrete failing field names into brightdata scraper heal. It never heals blind.