[{"data":1,"prerenderedAt":1700},["ShallowReactive",2],{"navigation":3,"\u002Fguides\u002Ftime-and-precision":170,"\u002Fguides\u002Ftime-and-precision-surround":1695},[4,25,104,150,160],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":6},"Getting Started",false,"\u002Fgetting-started","1.getting-started",[10,15,20],{"title":11,"path":12,"stem":13,"icon":14},"Introduction","\u002Fgetting-started\u002Fintroduction","1.getting-started\u002F1.introduction","i-lucide-book-open",{"title":16,"path":17,"stem":18,"icon":19},"Installation","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F2.installation","i-lucide-download",{"title":21,"path":22,"stem":23,"icon":24},"Quick start","\u002Fgetting-started\u002Fquick-start","1.getting-started\u002F3.quick-start","i-lucide-rocket",{"title":26,"icon":6,"path":27,"stem":28,"children":29,"page":6},"Guides","\u002Fguides","2.guides",[30,35,40,45,50,55,60,65,70,75,79,84,89,94,99],{"title":31,"path":32,"stem":33,"icon":34},"Seeds and TestBiome","\u002Fguides\u002Fseeds-and-testbiome","2.guides\u002F01.seeds-and-testbiome","i-lucide-sprout",{"title":36,"path":37,"stem":38,"icon":39},"Blueprints","\u002Fguides\u002Fblueprints","2.guides\u002F02.blueprints","i-lucide-drafting-compass",{"title":41,"path":42,"stem":43,"icon":44},"Customizing","\u002Fguides\u002Fcustomizing","2.guides\u002F03.customizing","i-lucide-sliders-horizontal",{"title":46,"path":47,"stem":48,"icon":49},"Parent\u002Fchild chains and .Under","\u002Fguides\u002Fparents-and-children","2.guides\u002F04.parents-and-children","i-lucide-git-fork",{"title":51,"path":52,"stem":53,"icon":54},"Fan-out","\u002Fguides\u002Ffan-out","2.guides\u002F05.fan-out","i-lucide-split",{"title":56,"path":57,"stem":58,"icon":59},"Sequences","\u002Fguides\u002Fsequences","2.guides\u002F06.sequences","i-lucide-list-ordered",{"title":61,"path":62,"stem":63,"icon":64},"Time and precision","\u002Fguides\u002Ftime-and-precision","2.guides\u002F07.time-and-precision","i-lucide-clock",{"title":66,"path":67,"stem":68,"icon":69},"Transients","\u002Fguides\u002Ftransients","2.guides\u002F08.transients","i-lucide-ghost",{"title":71,"path":72,"stem":73,"icon":74},"Aggregates","\u002Fguides\u002Faggregates","2.guides\u002F09.aggregates","i-lucide-boxes",{"title":76,"path":77,"stem":78,"icon":74},"Input blueprints","\u002Fguides\u002Finput-blueprints","2.guides\u002F09.input-blueprints",{"title":80,"path":81,"stem":82,"icon":83},"Save hooks and global defaults","\u002Fguides\u002Fsave-hooks-and-defaults","2.guides\u002F10.save-hooks-and-defaults","i-lucide-webhook",{"title":85,"path":86,"stem":87,"icon":88},"EF Core store","\u002Fguides\u002Fef-core-store","2.guides\u002F11.ef-core-store","i-lucide-database",{"title":90,"path":91,"stem":92,"icon":93},"No-DB unit tests","\u002Fguides\u002Fno-db-unit-tests","2.guides\u002F12.no-db-unit-tests","i-lucide-flask-conical",{"title":95,"path":96,"stem":97,"icon":98},"Generated grafts and scenario helpers","\u002Fguides\u002Fscenario-helpers-and-sugar","2.guides\u002F13.scenario-helpers-and-sugar","i-lucide-wand-sparkles",{"title":100,"path":101,"stem":102,"icon":103},"Constructor setup","\u002Fguides\u002Fconstructor-setup","2.guides\u002F14.constructor-setup","i-lucide-blocks",{"title":105,"path":106,"stem":107,"children":108,"icon":6},"Examples","\u002Fexamples","3.examples\u002F1.index",[109,111,116,121,126,130,135,140,145],{"title":105,"path":106,"stem":107,"icon":110},"i-lucide-library",{"title":112,"path":113,"stem":114,"icon":115},"Code reviews","\u002Fexamples\u002Fcode-reviews","3.examples\u002F2.code-reviews","i-lucide-git-pull-request",{"title":117,"path":118,"stem":119,"icon":120},"Membership","\u002Fexamples\u002Fmembership","3.examples\u002F3.membership","i-lucide-users",{"title":122,"path":123,"stem":124,"icon":125},"Board","\u002Fexamples\u002Fboard","3.examples\u002F4.board","i-lucide-kanban",{"title":127,"path":128,"stem":129,"icon":44},"Custom seed","\u002Fexamples\u002Fcustom-seed","3.examples\u002F5.custom-seed",{"title":131,"path":132,"stem":133,"icon":134},"Commerce","\u002Fexamples\u002Fcommerce","3.examples\u002F6.commerce","i-lucide-shopping-cart",{"title":136,"path":137,"stem":138,"icon":139},"Project management","\u002Fexamples\u002Fproject-management","3.examples\u002F7.project-management","i-lucide-folder-kanban",{"title":141,"path":142,"stem":143,"icon":144},"Learning","\u002Fexamples\u002Flearning","3.examples\u002F8.learning","i-lucide-graduation-cap",{"title":146,"path":147,"stem":148,"icon":149},"Docs ingest","\u002Fexamples\u002Fdocs-ingest","3.examples\u002F9.docs-ingest","i-lucide-file-search",{"title":151,"icon":6,"path":152,"stem":153,"children":154,"page":6},"Reference","\u002Freference","4.reference",[155],{"title":156,"path":157,"stem":158,"icon":159},"API cheat sheet","\u002Freference\u002Fapi-cheat-sheet","4.reference\u002F1.api-cheat-sheet","i-lucide-list-checks",{"title":161,"icon":6,"path":162,"stem":163,"children":164,"page":6},"Agent Skills","\u002Fagents","5.agents",[165],{"title":166,"path":167,"stem":168,"icon":169},"Agent skills","\u002Fagents\u002Fagent-skills","5.agents\u002F1.agent-skills","i-lucide-bot",{"id":171,"title":61,"body":172,"description":1688,"extension":1689,"links":1690,"meta":1691,"navigation":1692,"path":62,"seo":1693,"stem":63,"__hash__":1694},"docs\u002F2.guides\u002F07.time-and-precision.md",{"type":173,"value":174,"toc":1681},"minimark",[175,180,202,261,274,865,869,883,995,999,1002,1214,1218,1229,1386,1390,1404,1422,1623,1668,1677],[176,177,179],"h2",{"id":178},"one-clock","One clock",[181,182,183,184,188,189,193,194,197,198,201],"p",{},"Reading wall-clock time separately for each row can give related entities slightly different timestamps. That difference can obscure what the test intended. Biome gives each session ",[185,186,187],"strong",{},"one clock",", accessed in blueprints through ",[190,191,192],"code",{},"ctx.Now",", ",[190,195,196],{},"ctx.Ago(…)",", and ",[190,199,200],{},"ctx.FromNow(…)",".",[203,204,205,220],"table",{},[206,207,208],"thead",{},[209,210,211,215],"tr",{},[212,213,214],"th",{},"You pass…",[212,216,217,219],{},[190,218,192],{}," is…",[221,222,223,242],"tbody",{},[209,224,225,229],{},[226,227,228],"td",{},"no clock",[226,230,231,234,235,238,239,201],{},[185,232,233],{},"Frozen"," when ",[190,236,237],{},"Start"," is called. Every entity in the test sees the same ",[190,240,241],{},"Now",[209,243,244,250],{},[226,245,246,247],{},"a ",[190,248,249],{},"TimeProvider",[226,251,252,253,256,257,260],{},"Read ",[185,254,255],{},"live",". Advance a ",[190,258,259],{},"FakeTimeProvider"," during the test.",[262,263,264],"tip",{},[181,265,266,267,270,271,273],{},"An expiry test is easier to reason about when setup and the code under test read the ",[185,268,269],{},"same clock",". Pass one ",[190,272,259],{}," to both, then advance it to exercise the transition.",[275,276,277,499],"code-group",{},[278,279,292],"pre",{"className":280,"code":281,"filename":282,"highlights":283,"language":290,"meta":291,"style":291},"language-csharp shiki shiki-themes material-theme-lighter github-light github-dark","var time = new FakeTimeProvider(\n    new DateTimeOffset(2026, 10, 11, 12, 0, 0, TimeSpan.Zero)\n);\nawait TestBiome\n    .Start(out _, time: time)\n    .AddLockedReview(out var activeLock) \u002F\u002F ExpiresAtUtc = 12:05\n    .BuildAsync();\n\n\u002F\u002F the SUT reads the same clock: the lock has expired\ntime.Advance(TimeSpan.FromMinutes(6));\n","With Biome",[284,285,286,287,288,289],1,2,3,4,5,10,"csharp","",[190,293,294,322,377,383,392,421,446,457,464,470],{"__ignoreMap":291},[295,296,300,304,308,312,315,318],"span",{"class":297,"line":284},[298,299],"line","highlight",[295,301,303],{"class":302},"sG8yY","var",[295,305,307],{"class":306},"sbgvK"," time",[295,309,311],{"class":310},"smGrS"," =",[295,313,314],{"class":310}," new",[295,316,317],{"class":306}," FakeTimeProvider",[295,319,321],{"class":320},"sP7_E","(\n",[295,323,325,328,331,334,338,341,344,346,349,351,354,356,359,361,363,365,369,371,374],{"class":324,"line":285},[298,299],[295,326,327],{"class":310},"    new",[295,329,330],{"class":306}," DateTimeOffset",[295,332,333],{"class":320},"(",[295,335,337],{"class":336},"srdBf","2026",[295,339,340],{"class":320},",",[295,342,343],{"class":336}," 10",[295,345,340],{"class":320},[295,347,348],{"class":336}," 11",[295,350,340],{"class":320},[295,352,353],{"class":336}," 12",[295,355,340],{"class":320},[295,357,358],{"class":336}," 0",[295,360,340],{"class":320},[295,362,358],{"class":336},[295,364,340],{"class":320},[295,366,368],{"class":367},"su5hD"," TimeSpan",[295,370,201],{"class":320},[295,372,373],{"class":367},"Zero",[295,375,376],{"class":320},")\n",[295,378,380],{"class":379,"line":286},[298,299],[295,381,382],{"class":320},");\n",[295,384,386,389],{"class":385,"line":287},[298,299],[295,387,388],{"class":310},"await",[295,390,391],{"class":367}," TestBiome\n",[295,393,395,398,401,403,407,410,412,414,417,419],{"class":394,"line":288},[298,299],[295,396,397],{"class":320},"    .",[295,399,237],{"class":400},"sGLFI",[295,402,333],{"class":320},[295,404,406],{"class":405},"sbsja","out",[295,408,409],{"class":367}," _",[295,411,340],{"class":320},[295,413,307],{"class":306},[295,415,416],{"class":320},":",[295,418,307],{"class":367},[295,420,376],{"class":320},[295,422,424,426,429,431,433,436,439,442],{"class":298,"line":423},6,[295,425,397],{"class":320},[295,427,428],{"class":400},"AddLockedReview",[295,430,333],{"class":320},[295,432,406],{"class":405},[295,434,435],{"class":302}," var",[295,437,438],{"class":306}," activeLock",[295,440,441],{"class":320},")",[295,443,445],{"class":444},"sutJx"," \u002F\u002F ExpiresAtUtc = 12:05\n",[295,447,449,451,454],{"class":298,"line":448},7,[295,450,397],{"class":320},[295,452,453],{"class":400},"BuildAsync",[295,455,456],{"class":320},"();\n",[295,458,460],{"class":298,"line":459},8,[295,461,463],{"emptyLinePlaceholder":462},true,"\n",[295,465,467],{"class":298,"line":466},9,[295,468,469],{"class":444},"\u002F\u002F the SUT reads the same clock: the lock has expired\n",[295,471,473,476,478,481,483,486,488,491,493,496],{"class":472,"line":289},[298,299],[295,474,475],{"class":367},"time",[295,477,201],{"class":320},[295,479,480],{"class":400},"Advance",[295,482,333],{"class":320},[295,484,485],{"class":367},"TimeSpan",[295,487,201],{"class":320},[295,489,490],{"class":400},"FromMinutes",[295,492,333],{"class":320},[295,494,495],{"class":336},"6",[295,497,498],{"class":320},"));\n",[500,501,504],"code-collapse",{"label":502,"name":503},"Without Biome","setup",[278,505,507],{"className":280,"code":506,"language":290,"meta":291,"style":291},"\u002F\u002F Wall-clock time in setup, a separate fake clock\n\u002F\u002F in the SUT, and arithmetic by hand.\nvar start = new DateTimeOffset(2026, 10, 11, 12, 0, 0, TimeSpan.Zero);\nvar time = new FakeTimeProvider(start);\n\nvar repo = new CodeRepository\n{ \u002F* … *\u002F\n    CreatedAtUtc = start,\n};\nvar pr = new PullRequestRecord\n{ \u002F* … *\u002F\n    CreatedAtUtc = start,\n};\nvar review = new CodeReviewRecord\n{ \u002F* … *\u002F\n    CreatedAtUtc = start,\n};\nvar activeLock = new ActiveCodeReviewLock\n{\n    \u002F* … *\u002F\n    AcquiredAtUtc = start,\n    ExpiresAtUtc = start.AddMinutes(5), \u002F\u002F repeated in every test that needs a lock\n};\n_db.AddRange(seed.Owner, seed.Organization, repo, pr, review, activeLock);\nawait _db.SaveChangesAsync();\n\ntime.Advance(TimeSpan.FromMinutes(6));\n",[190,508,509,514,519,566,585,589,603,611,624,629,643,650,661,666,681,688,699,704,718,724,730,742,768,773,822,837,842],{"__ignoreMap":291},[295,510,511],{"class":298,"line":284},[295,512,513],{"class":444},"\u002F\u002F Wall-clock time in setup, a separate fake clock\n",[295,515,516],{"class":298,"line":285},[295,517,518],{"class":444},"\u002F\u002F in the SUT, and arithmetic by hand.\n",[295,520,521,523,526,528,530,532,534,536,538,540,542,544,546,548,550,552,554,556,558,560,562,564],{"class":298,"line":286},[295,522,303],{"class":302},[295,524,525],{"class":306}," start",[295,527,311],{"class":310},[295,529,314],{"class":310},[295,531,330],{"class":306},[295,533,333],{"class":320},[295,535,337],{"class":336},[295,537,340],{"class":320},[295,539,343],{"class":336},[295,541,340],{"class":320},[295,543,348],{"class":336},[295,545,340],{"class":320},[295,547,353],{"class":336},[295,549,340],{"class":320},[295,551,358],{"class":336},[295,553,340],{"class":320},[295,555,358],{"class":336},[295,557,340],{"class":320},[295,559,368],{"class":367},[295,561,201],{"class":320},[295,563,373],{"class":367},[295,565,382],{"class":320},[295,567,568,570,572,574,576,578,580,583],{"class":298,"line":287},[295,569,303],{"class":302},[295,571,307],{"class":306},[295,573,311],{"class":310},[295,575,314],{"class":310},[295,577,317],{"class":306},[295,579,333],{"class":320},[295,581,582],{"class":367},"start",[295,584,382],{"class":320},[295,586,587],{"class":298,"line":288},[295,588,463],{"emptyLinePlaceholder":462},[295,590,591,593,596,598,600],{"class":298,"line":423},[295,592,303],{"class":302},[295,594,595],{"class":306}," repo",[295,597,311],{"class":310},[295,599,314],{"class":310},[295,601,602],{"class":306}," CodeRepository\n",[295,604,605,608],{"class":298,"line":448},[295,606,607],{"class":320},"{",[295,609,610],{"class":444}," \u002F* … *\u002F\n",[295,612,613,616,619,621],{"class":298,"line":459},[295,614,615],{"class":367},"    CreatedAtUtc ",[295,617,618],{"class":310},"=",[295,620,525],{"class":367},[295,622,623],{"class":320},",\n",[295,625,626],{"class":298,"line":466},[295,627,628],{"class":320},"};\n",[295,630,631,633,636,638,640],{"class":298,"line":289},[295,632,303],{"class":302},[295,634,635],{"class":306}," pr",[295,637,311],{"class":310},[295,639,314],{"class":310},[295,641,642],{"class":306}," PullRequestRecord\n",[295,644,646,648],{"class":298,"line":645},11,[295,647,607],{"class":320},[295,649,610],{"class":444},[295,651,653,655,657,659],{"class":298,"line":652},12,[295,654,615],{"class":367},[295,656,618],{"class":310},[295,658,525],{"class":367},[295,660,623],{"class":320},[295,662,664],{"class":298,"line":663},13,[295,665,628],{"class":320},[295,667,669,671,674,676,678],{"class":298,"line":668},14,[295,670,303],{"class":302},[295,672,673],{"class":306}," review",[295,675,311],{"class":310},[295,677,314],{"class":310},[295,679,680],{"class":306}," CodeReviewRecord\n",[295,682,684,686],{"class":298,"line":683},15,[295,685,607],{"class":320},[295,687,610],{"class":444},[295,689,691,693,695,697],{"class":298,"line":690},16,[295,692,615],{"class":367},[295,694,618],{"class":310},[295,696,525],{"class":367},[295,698,623],{"class":320},[295,700,702],{"class":298,"line":701},17,[295,703,628],{"class":320},[295,705,707,709,711,713,715],{"class":298,"line":706},18,[295,708,303],{"class":302},[295,710,438],{"class":306},[295,712,311],{"class":310},[295,714,314],{"class":310},[295,716,717],{"class":306}," ActiveCodeReviewLock\n",[295,719,721],{"class":298,"line":720},19,[295,722,723],{"class":320},"{\n",[295,725,727],{"class":298,"line":726},20,[295,728,729],{"class":444},"    \u002F* … *\u002F\n",[295,731,733,736,738,740],{"class":298,"line":732},21,[295,734,735],{"class":367},"    AcquiredAtUtc ",[295,737,618],{"class":310},[295,739,525],{"class":367},[295,741,623],{"class":320},[295,743,745,748,750,752,754,757,759,762,765],{"class":298,"line":744},22,[295,746,747],{"class":367},"    ExpiresAtUtc ",[295,749,618],{"class":310},[295,751,525],{"class":367},[295,753,201],{"class":320},[295,755,756],{"class":400},"AddMinutes",[295,758,333],{"class":320},[295,760,761],{"class":336},"5",[295,763,764],{"class":320},"),",[295,766,767],{"class":444}," \u002F\u002F repeated in every test that needs a lock\n",[295,769,771],{"class":298,"line":770},23,[295,772,628],{"class":320},[295,774,776,779,781,784,786,789,791,794,796,799,801,804,806,808,810,812,814,816,818,820],{"class":298,"line":775},24,[295,777,778],{"class":367},"_db",[295,780,201],{"class":320},[295,782,783],{"class":400},"AddRange",[295,785,333],{"class":320},[295,787,788],{"class":367},"seed",[295,790,201],{"class":320},[295,792,793],{"class":367},"Owner",[295,795,340],{"class":320},[295,797,798],{"class":367}," seed",[295,800,201],{"class":320},[295,802,803],{"class":367},"Organization",[295,805,340],{"class":320},[295,807,595],{"class":367},[295,809,340],{"class":320},[295,811,635],{"class":367},[295,813,340],{"class":320},[295,815,673],{"class":367},[295,817,340],{"class":320},[295,819,438],{"class":367},[295,821,382],{"class":320},[295,823,825,827,830,832,835],{"class":298,"line":824},25,[295,826,388],{"class":310},[295,828,829],{"class":367}," _db",[295,831,201],{"class":320},[295,833,834],{"class":400},"SaveChangesAsync",[295,836,456],{"class":320},[295,838,840],{"class":298,"line":839},26,[295,841,463],{"emptyLinePlaceholder":462},[295,843,845,847,849,851,853,855,857,859,861,863],{"class":298,"line":844},27,[295,846,475],{"class":367},[295,848,201],{"class":320},[295,850,480],{"class":400},[295,852,333],{"class":320},[295,854,485],{"class":367},[295,856,201],{"class":320},[295,858,490],{"class":400},[295,860,333],{"class":320},[295,862,495],{"class":336},[295,864,498],{"class":320},[176,866,868],{"id":867},"frozen-by-default","Frozen by default",[181,870,871,872,875,876,879,880,882],{},"Without a provider, Biome captures ",[190,873,874],{},"TimeProvider.System.GetUtcNow()"," ",[185,877,878],{},"once"," at ",[190,881,237],{},". Entities built a moment apart still get identical timestamps:",[278,884,888],{"className":280,"code":885,"filename":886,"highlights":887,"language":290,"meta":291,"style":291},"var biome = TestBiome.Start(out _);\n\nbiome.AddCodeRepository(out var first);\nawait Task.Delay(20);\nawait biome.AddCodeRepository(out var second).BuildAsync();\n\n\u002F\u002F second.CreatedAt == first.CreatedAt, and first.CreatedAt.Ticks % 10 == 0\n","CodeReviewTests.cs",[287,288],[190,889,890,914,918,939,959,986,990],{"__ignoreMap":291},[295,891,892,894,897,899,902,904,906,908,910,912],{"class":298,"line":284},[295,893,303],{"class":302},[295,895,896],{"class":306}," biome",[295,898,311],{"class":310},[295,900,901],{"class":367}," TestBiome",[295,903,201],{"class":320},[295,905,237],{"class":400},[295,907,333],{"class":320},[295,909,406],{"class":405},[295,911,409],{"class":367},[295,913,382],{"class":320},[295,915,916],{"class":298,"line":285},[295,917,463],{"emptyLinePlaceholder":462},[295,919,920,923,925,928,930,932,934,937],{"class":298,"line":286},[295,921,922],{"class":367},"biome",[295,924,201],{"class":320},[295,926,927],{"class":400},"AddCodeRepository",[295,929,333],{"class":320},[295,931,406],{"class":405},[295,933,435],{"class":302},[295,935,936],{"class":306}," first",[295,938,382],{"class":320},[295,940,942,944,947,949,952,954,957],{"class":941,"line":287},[298,299],[295,943,388],{"class":310},[295,945,946],{"class":367}," Task",[295,948,201],{"class":320},[295,950,951],{"class":400},"Delay",[295,953,333],{"class":320},[295,955,956],{"class":336},"20",[295,958,382],{"class":320},[295,960,962,964,966,968,970,972,974,976,979,982,984],{"class":961,"line":288},[298,299],[295,963,388],{"class":310},[295,965,896],{"class":367},[295,967,201],{"class":320},[295,969,927],{"class":400},[295,971,333],{"class":320},[295,973,406],{"class":405},[295,975,435],{"class":302},[295,977,978],{"class":306}," second",[295,980,981],{"class":320},").",[295,983,453],{"class":400},[295,985,456],{"class":320},[295,987,988],{"class":298,"line":423},[295,989,463],{"emptyLinePlaceholder":462},[295,991,992],{"class":298,"line":448},[295,993,994],{"class":444},"\u002F\u002F second.CreatedAt == first.CreatedAt, and first.CreatedAt.Ticks % 10 == 0\n",[176,996,998],{"id":997},"a-live-clock-between-adds","A live clock between Adds",[181,1000,1001],{},"Adds are eager, so a test can advance the provider between Add calls before the single save:",[278,1003,1007],{"className":280,"code":1004,"filename":1005,"highlights":1006,"language":290,"meta":291,"style":291},"var instant = new DateTimeOffset(2026, 10, 11, 12, 0, 0, TimeSpan.Zero);\nvar time = new FakeTimeProvider(instant);\nvar biome = TestBiome.Start(out _, time: time);\nbiome.AddTrackedOrder(out var first);\n\n\u002F\u002F Eager construction lets a test advance time\n\u002F\u002F between Add calls before the single save.\ntime.Advance(TimeSpan.FromHours(2));\nawait biome.Under(first.Shipment).AddTrackingEvent(out var later).BuildAsync();\n\n\u002F\u002F first.OccurredAt is unchanged; later.OccurredAt uses the advanced clock.\n","CommerceTests.cs",[459,466],[190,1008,1009,1056,1075,1105,1124,1128,1133,1138,1163,1205,1209],{"__ignoreMap":291},[295,1010,1011,1013,1016,1018,1020,1022,1024,1026,1028,1030,1032,1034,1036,1038,1040,1042,1044,1046,1048,1050,1052,1054],{"class":298,"line":284},[295,1012,303],{"class":302},[295,1014,1015],{"class":306}," instant",[295,1017,311],{"class":310},[295,1019,314],{"class":310},[295,1021,330],{"class":306},[295,1023,333],{"class":320},[295,1025,337],{"class":336},[295,1027,340],{"class":320},[295,1029,343],{"class":336},[295,1031,340],{"class":320},[295,1033,348],{"class":336},[295,1035,340],{"class":320},[295,1037,353],{"class":336},[295,1039,340],{"class":320},[295,1041,358],{"class":336},[295,1043,340],{"class":320},[295,1045,358],{"class":336},[295,1047,340],{"class":320},[295,1049,368],{"class":367},[295,1051,201],{"class":320},[295,1053,373],{"class":367},[295,1055,382],{"class":320},[295,1057,1058,1060,1062,1064,1066,1068,1070,1073],{"class":298,"line":285},[295,1059,303],{"class":302},[295,1061,307],{"class":306},[295,1063,311],{"class":310},[295,1065,314],{"class":310},[295,1067,317],{"class":306},[295,1069,333],{"class":320},[295,1071,1072],{"class":367},"instant",[295,1074,382],{"class":320},[295,1076,1077,1079,1081,1083,1085,1087,1089,1091,1093,1095,1097,1099,1101,1103],{"class":298,"line":286},[295,1078,303],{"class":302},[295,1080,896],{"class":306},[295,1082,311],{"class":310},[295,1084,901],{"class":367},[295,1086,201],{"class":320},[295,1088,237],{"class":400},[295,1090,333],{"class":320},[295,1092,406],{"class":405},[295,1094,409],{"class":367},[295,1096,340],{"class":320},[295,1098,307],{"class":306},[295,1100,416],{"class":320},[295,1102,307],{"class":367},[295,1104,382],{"class":320},[295,1106,1107,1109,1111,1114,1116,1118,1120,1122],{"class":298,"line":287},[295,1108,922],{"class":367},[295,1110,201],{"class":320},[295,1112,1113],{"class":400},"AddTrackedOrder",[295,1115,333],{"class":320},[295,1117,406],{"class":405},[295,1119,435],{"class":302},[295,1121,936],{"class":306},[295,1123,382],{"class":320},[295,1125,1126],{"class":298,"line":288},[295,1127,463],{"emptyLinePlaceholder":462},[295,1129,1130],{"class":298,"line":423},[295,1131,1132],{"class":444},"\u002F\u002F Eager construction lets a test advance time\n",[295,1134,1135],{"class":298,"line":448},[295,1136,1137],{"class":444},"\u002F\u002F between Add calls before the single save.\n",[295,1139,1141,1143,1145,1147,1149,1151,1153,1156,1158,1161],{"class":1140,"line":459},[298,299],[295,1142,475],{"class":367},[295,1144,201],{"class":320},[295,1146,480],{"class":400},[295,1148,333],{"class":320},[295,1150,485],{"class":367},[295,1152,201],{"class":320},[295,1154,1155],{"class":400},"FromHours",[295,1157,333],{"class":320},[295,1159,1160],{"class":336},"2",[295,1162,498],{"class":320},[295,1164,1166,1168,1170,1172,1175,1177,1180,1182,1185,1187,1190,1192,1194,1196,1199,1201,1203],{"class":1165,"line":466},[298,299],[295,1167,388],{"class":310},[295,1169,896],{"class":367},[295,1171,201],{"class":320},[295,1173,1174],{"class":400},"Under",[295,1176,333],{"class":320},[295,1178,1179],{"class":367},"first",[295,1181,201],{"class":320},[295,1183,1184],{"class":367},"Shipment",[295,1186,981],{"class":320},[295,1188,1189],{"class":400},"AddTrackingEvent",[295,1191,333],{"class":320},[295,1193,406],{"class":405},[295,1195,435],{"class":302},[295,1197,1198],{"class":306}," later",[295,1200,981],{"class":320},[295,1202,453],{"class":400},[295,1204,456],{"class":320},[295,1206,1207],{"class":298,"line":289},[295,1208,463],{"emptyLinePlaceholder":462},[295,1210,1211],{"class":298,"line":645},[295,1212,1213],{"class":444},"\u002F\u002F first.OccurredAt is unchanged; later.OccurredAt uses the advanced clock.\n",[176,1215,1217],{"id":1216},"relative-times","Relative times",[181,1219,1220,1221,1224,1225,1228],{},"Use the two-parameter form with ",[190,1222,1223],{},"ctx.Ago"," \u002F ",[190,1226,1227],{},"ctx.FromNow",". It works with any clock:",[278,1230,1234],{"className":280,"code":1231,"filename":1232,"highlights":1233,"language":290,"meta":291,"style":291},"await TestBiome\n    .Start(out _)\n    .AddCodeRepository(out _)\n    .AddPullRequest(out _)\n    .AddOne(\n        Blueprints.Review,\n        out var stale,\n        (r, ctx) => r.CreatedAtUtc = ctx.Ago(TimeSpan.FromHours(2))\n    )\n    .BuildAsync();\n","Relative",[288,423,448,459,466],[190,1235,1236,1242,1256,1270,1285,1295,1308,1321,1372,1378],{"__ignoreMap":291},[295,1237,1238,1240],{"class":298,"line":284},[295,1239,388],{"class":310},[295,1241,391],{"class":367},[295,1243,1244,1246,1248,1250,1252,1254],{"class":298,"line":285},[295,1245,397],{"class":320},[295,1247,237],{"class":400},[295,1249,333],{"class":320},[295,1251,406],{"class":405},[295,1253,409],{"class":367},[295,1255,376],{"class":320},[295,1257,1258,1260,1262,1264,1266,1268],{"class":298,"line":286},[295,1259,397],{"class":320},[295,1261,927],{"class":400},[295,1263,333],{"class":320},[295,1265,406],{"class":405},[295,1267,409],{"class":367},[295,1269,376],{"class":320},[295,1271,1272,1274,1277,1279,1281,1283],{"class":298,"line":287},[295,1273,397],{"class":320},[295,1275,1276],{"class":400},"AddPullRequest",[295,1278,333],{"class":320},[295,1280,406],{"class":405},[295,1282,409],{"class":367},[295,1284,376],{"class":320},[295,1286,1288,1290,1293],{"class":1287,"line":288},[298,299],[295,1289,397],{"class":320},[295,1291,1292],{"class":400},"AddOne",[295,1294,321],{"class":320},[295,1296,1298,1301,1303,1306],{"class":1297,"line":423},[298,299],[295,1299,1300],{"class":367},"        Blueprints",[295,1302,201],{"class":320},[295,1304,1305],{"class":367},"Review",[295,1307,623],{"class":320},[295,1309,1311,1314,1316,1319],{"class":1310,"line":448},[298,299],[295,1312,1313],{"class":405},"        out",[295,1315,435],{"class":302},[295,1317,1318],{"class":306}," stale",[295,1320,623],{"class":320},[295,1322,1324,1327,1330,1332,1335,1337,1340,1343,1345,1348,1350,1352,1354,1357,1359,1361,1363,1365,1367,1369],{"class":1323,"line":459},[298,299],[295,1325,1326],{"class":320},"        (",[295,1328,1329],{"class":306},"r",[295,1331,340],{"class":320},[295,1333,1334],{"class":306}," ctx",[295,1336,441],{"class":320},[295,1338,1339],{"class":310}," =>",[295,1341,1342],{"class":367}," r",[295,1344,201],{"class":320},[295,1346,1347],{"class":367},"CreatedAtUtc ",[295,1349,618],{"class":310},[295,1351,1334],{"class":367},[295,1353,201],{"class":320},[295,1355,1356],{"class":400},"Ago",[295,1358,333],{"class":320},[295,1360,485],{"class":367},[295,1362,201],{"class":320},[295,1364,1155],{"class":400},[295,1366,333],{"class":320},[295,1368,1160],{"class":336},[295,1370,1371],{"class":320},"))\n",[295,1373,1375],{"class":1374,"line":466},[298,299],[295,1376,1377],{"class":320},"    )\n",[295,1379,1380,1382,1384],{"class":298,"line":289},[295,1381,397],{"class":320},[295,1383,453],{"class":400},[295,1385,456],{"class":320},[176,1387,1389],{"id":1388},"precision-rounding","Precision rounding",[1391,1392,1393],"note",{},[181,1394,1395,1396,1399,1400,1403],{},"A timestamp can be correct in memory and still change on a database round trip. Biome rounds clock readings to ",[185,1397,1398],{},"1 µs by default"," to match Postgres ",[190,1401,1402],{},"timestamptz",", so values built from those readings retain their precision when saved.",[181,1405,1406,1407,1410,1411,1414,1415,1417,1418,1421],{},".NET stores 100 ns ticks. Postgres stores microseconds. An unrounded ",[190,1408,1409],{},"DateTimeOffset.UtcNow"," loses its last digit on a round trip, and an equality assertion then fails in CI only. Biome truncates every reading of \"now\" (frozen ",[185,1412,1413],{},"and"," test-supplied) before ",[190,1416,1356],{}," and ",[190,1419,1420],{},"FromNow"," derive from it.",[278,1423,1427],{"className":280,"code":1424,"filename":1425,"highlights":1426,"language":290,"meta":291,"style":291},"\u002F\u002F Seven fractional digits: the last tick is below Postgres precision.\nvar instant = new DateTimeOffset(2026, 10, 11, 12, 0, 0, TimeSpan.Zero).AddTicks(\n    1_234_567\n);\nvar time = new FakeTimeProvider(instant);\n\nawait TestBiome.Start(db, out _, time).AddCodeRepository(out var repo).BuildAsync();\n\nvar saved = await read.Repositories.SingleAsync(r => r.Id == repo.Id);\n\u002F\u002F saved.CreatedAt == repo.CreatedAt   (and == instant.AddTicks(-7))\n","PostgresTimeTests.cs",[285,286,287,448],[190,1428,1429,1434,1486,1492,1497,1515,1519,1564,1568,1618],{"__ignoreMap":291},[295,1430,1431],{"class":298,"line":284},[295,1432,1433],{"class":444},"\u002F\u002F Seven fractional digits: the last tick is below Postgres precision.\n",[295,1435,1437,1439,1441,1443,1445,1447,1449,1451,1453,1455,1457,1459,1461,1463,1465,1467,1469,1471,1473,1475,1477,1479,1481,1484],{"class":1436,"line":285},[298,299],[295,1438,303],{"class":302},[295,1440,1015],{"class":306},[295,1442,311],{"class":310},[295,1444,314],{"class":310},[295,1446,330],{"class":306},[295,1448,333],{"class":320},[295,1450,337],{"class":336},[295,1452,340],{"class":320},[295,1454,343],{"class":336},[295,1456,340],{"class":320},[295,1458,348],{"class":336},[295,1460,340],{"class":320},[295,1462,353],{"class":336},[295,1464,340],{"class":320},[295,1466,358],{"class":336},[295,1468,340],{"class":320},[295,1470,358],{"class":336},[295,1472,340],{"class":320},[295,1474,368],{"class":367},[295,1476,201],{"class":320},[295,1478,373],{"class":367},[295,1480,981],{"class":320},[295,1482,1483],{"class":400},"AddTicks",[295,1485,321],{"class":320},[295,1487,1489],{"class":1488,"line":286},[298,299],[295,1490,1491],{"class":336},"    1_234_567\n",[295,1493,1495],{"class":1494,"line":287},[298,299],[295,1496,382],{"class":320},[295,1498,1499,1501,1503,1505,1507,1509,1511,1513],{"class":298,"line":288},[295,1500,303],{"class":302},[295,1502,307],{"class":306},[295,1504,311],{"class":310},[295,1506,314],{"class":310},[295,1508,317],{"class":306},[295,1510,333],{"class":320},[295,1512,1072],{"class":367},[295,1514,382],{"class":320},[295,1516,1517],{"class":298,"line":423},[295,1518,463],{"emptyLinePlaceholder":462},[295,1520,1522,1524,1526,1528,1530,1532,1535,1537,1540,1542,1544,1546,1548,1550,1552,1554,1556,1558,1560,1562],{"class":1521,"line":448},[298,299],[295,1523,388],{"class":310},[295,1525,901],{"class":367},[295,1527,201],{"class":320},[295,1529,237],{"class":400},[295,1531,333],{"class":320},[295,1533,1534],{"class":367},"db",[295,1536,340],{"class":320},[295,1538,1539],{"class":405}," out",[295,1541,409],{"class":367},[295,1543,340],{"class":320},[295,1545,307],{"class":367},[295,1547,981],{"class":320},[295,1549,927],{"class":400},[295,1551,333],{"class":320},[295,1553,406],{"class":405},[295,1555,435],{"class":302},[295,1557,595],{"class":306},[295,1559,981],{"class":320},[295,1561,453],{"class":400},[295,1563,456],{"class":320},[295,1565,1566],{"class":298,"line":459},[295,1567,463],{"emptyLinePlaceholder":462},[295,1569,1570,1572,1575,1577,1580,1583,1585,1588,1590,1593,1595,1597,1599,1601,1603,1606,1609,1611,1613,1616],{"class":298,"line":466},[295,1571,303],{"class":302},[295,1573,1574],{"class":306}," saved",[295,1576,311],{"class":310},[295,1578,1579],{"class":310}," await",[295,1581,1582],{"class":367}," read",[295,1584,201],{"class":320},[295,1586,1587],{"class":367},"Repositories",[295,1589,201],{"class":320},[295,1591,1592],{"class":400},"SingleAsync",[295,1594,333],{"class":320},[295,1596,1329],{"class":306},[295,1598,1339],{"class":310},[295,1600,1342],{"class":367},[295,1602,201],{"class":320},[295,1604,1605],{"class":367},"Id ",[295,1607,1608],{"class":310},"==",[295,1610,595],{"class":367},[295,1612,201],{"class":320},[295,1614,1615],{"class":367},"Id",[295,1617,382],{"class":320},[295,1619,1620],{"class":298,"line":289},[295,1621,1622],{"class":444},"\u002F\u002F saved.CreatedAt == repo.CreatedAt   (and == instant.AddTicks(-7))\n",[203,1624,1625,1635],{},[206,1626,1627],{},[209,1628,1629,1632],{},[212,1630,1631],{},"Option",[212,1633,1634],{},"Effect",[221,1636,1637,1648,1658],{},[209,1638,1639,1642],{},[226,1640,1641],{},"default",[226,1643,1644,1645,981],{},"1 µs (",[190,1646,1647],{},"TimeSpan.FromTicks(10)",[209,1649,1650,1655],{},[226,1651,1652],{},[190,1653,1654],{},"options.TimePrecision(TimeSpan.FromMilliseconds(1))",[226,1656,1657],{},"Round to a millisecond.",[209,1659,1660,1665],{},[226,1661,1662],{},[190,1663,1664],{},"options.TimePrecision(TimeSpan.Zero)",[226,1666,1667],{},"Turn rounding off.",[1669,1670,1671],"warning",{},[181,1672,1673,1674,1676],{},"If timestamps differ by ticks or microseconds after a read, check whether setup used a separate wall-clock reading. Use the session clock or the shared ",[190,1675,259],{}," for comparisons, so precision and elapsed time do not introduce an unrelated difference.",[1678,1679,1680],"style",{},"html pre.shiki code .sG8yY, html code.shiki .sG8yY{--shiki-light:#E2931D;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .srdBf, html code.shiki .srdBf{--shiki-light:#F76D47;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":291,"searchDepth":284,"depth":285,"links":1682},[1683,1684,1685,1686,1687],{"id":178,"depth":285,"text":179},{"id":867,"depth":285,"text":868},{"id":997,"depth":285,"text":998},{"id":1216,"depth":285,"text":1217},{"id":1388,"depth":285,"text":1389},"One clock per test, frozen or shared with the code under test, rounded to match your database.","md",null,{},{"icon":64},{"title":61,"description":1688},"xB35uI31HNuKFfqHheZS--HqLfvmS6XV7rckxCKPJS0",[1696,1698],{"title":56,"path":57,"stem":58,"description":1697,"icon":59,"children":-1},"Numbers and ordering that continue across Add calls, per session, parent or ancestor.",{"title":66,"path":67,"stem":68,"description":1699,"icon":69,"children":-1},"Build an entity and return it, without saving it.",1791831052198]