Մուտքագրեք վայրկյանում թոքենների թիվ այս կայքի որևէ էջում, և CI-ն կձախողվի։ Դրեք այն այնպես, ինչպես կանոնները թույլ են տալիս՝ claim id-ի միջոցով, բայց id-ն սխալ գրեք, և ստատիկ build-ը սխալ կգցի, նախքան deploy անելու բան կլինի։ Սա վերակառուցման առաջին նախագծային որոշումն էր։
Կանոնն այս է. չափված արժեքն էջ է հասնում միայն կոմպոնենտի միջոցով, որը claim id է ընդունում; այդ կանոնի այն մասը, որ թողունակության տեսք ունեցող թվերին է վերաբերում, պարտադրում է սկաները, մնացածը՝ ես։ Անհայտ id-ն սխալ է գցում՝ հաղորդագրությամբ, որ նախ պետք է ավելացնել վավեր գործարկումներով հիմնավորված claim։ Եթե claim-ը կա, բայց superseded է կամ retracted, նույնպես սխալ է գցում, որովհետև փոխարինված թիվը նախադասության մեջ պտտվելու ոչ մի գործ չունի։ Ռենդերվում է արժեքը, նրա միավորը և հղում դեպի մշտական էջ, որը կրում է claim-ի շրջանակը, սահմանափակումներն ու գործարկումները։
Ռեեստրը գեներացվում է, երբեք չի խմբագրվում։ Դրանից մի քայլ վերև claim-ը JSON ֆայլ է, որն արդեն ես եմ ձեռքով գրում. բառերով ձևակերպված պնդում, գործարկումների id-ները, որոնց վրա այն հենվում է, SQL ֆայլի ուղին, շրջանակը, սահմանափակումները, ապացույցի մակարդակը և կարգավիճակը։ Արժեքը միակ դաշտն է, որն այնտեղ չկա։ Սկրիպտն ամեն claim-ի query-ն DuckDB-ով քշում է հենց և միայն claim-ում նշված գործարկումների՝ հարցում առ հարցում պահված գրառումների վրա, նայում է, թե որ մեքենան ու մոդելի որ արտեֆակտն են այդ գործարկումներն օգտագործել, և արդյունքը գրում է մեկ գեներացված TypeScript ֆայլի մեջ, որի սկզբում գրված է՝ չխմբագրել։ CI-ն նույն սկրիպտը քշում է ստուգման ռեժիմով և ձախողվում է, երբ commit-ված ֆայլը տարբերվում է հենց նոր արտածածից։ Խմբագրեք արժեքը ձեռքով կամ ձեռք տվեք գործարկմանը՝ առանց նորից արտածելու, և խողովակաշարը կկանգնի։ Ռեեստրը հրապարակվում է նաև որպես JSON և որպես markdown-երկվորյակ՝ ամեն claim-ի համար։
Ես սա այսպես չկառուցեցի գեղեցկության համար։ Վերակառուցումն ուներ մեկ գործ. թիվը չպետք է կարողանա ապրել իր ապացույցից ավելի երկար։ Ռեեստրը ծնվեց դատարկ և կայքի բացվելուց հետո օրերով դատարկ մնաց; թվեր պահելու համար նախատեսված էջերը դատարկ վիճակներ էին ցույց տալիս, իսկ ռեեստրի ֆայլի վերևի մեկնաբանությունը մինչև հիմա ասում է, որ legacy թվերը հետ ավելացնել չի կարելի։ Այսօր ռեեստրը մի քանի տասնյակ claim է պահում։ Ամեն ձևակերպումն ես եմ գրել, և ոչ մի արժեք չեմ մուտքագրել։
Ինչ է պարտադրում CI-ն
Հայտարարն ապրում է SQL-ի մեջ, ոչ թե մեթոդաբանության էջում։ Answerless հարցումների claim-ի հետևում կանգնած query-ն մեկնաբանություն է կրում. հայտարարը նշված գործարկումներում տրված ամեն հարցումն է, ձախողումները երբեք դուրս չեն գցվում։ Մեկնաբանության տակի SELECT-ը հենց դա էլ անում է. բաժանում է հասարակ count-ի վրա, որը հաշվում է claim-ում նշված գործարկումների ամեն մի գրառում։
Վալիդատորը պետք է ապացուցի, որ կարող է «ոչ» ասել, նույն պատճառով, որով harness-ը պահում է իր անվավեր առաջին գործարկումը։ Կատալոգի կողքին մինի-կատալոգների թղթապանակ կա, որոնք հավաքված են մերժվելու համար. ակտիվ claim դեռ planned նշված գործարկման վրա, երկու workload ընդգրկող claim, համակարգերի վրայով ագրեգացնող claim առանց համեմատության դասի, մոդել առանց հեշի, գործարկում, որի հղումները ոչ մի տեղ չեն տանում։ Կատալոգի gate-ը ձախողվում է, եթե դրանցից որևէ մեկն ընդունի։ Վալիդատորը, որին ոչ ոք երբեք որևէ բան մերժելիս չի տեսել, ֆորմատավորման քայլ է՝ ինքնավստահ անունով։
Պատմական մեջբերումները տողի վրա մարկեր են պահանջում։ Բառապաշարի սկաներն էջի տեքստում ձեռքով մուտքագրված թողունակության թիվ չի ընդունում, եթե տողը չի կրում փոքրիկ HTML մեկնաբանություն, որը նշանակում է «ստուգված մեջբերում նշված աղբյուրից»։ Ուրիշների հրապարակումների թվերը կարող են հայտնվել; մերոնց նմանվել՝ չեն կարող։
Առաջին մի քանի օրը դրեյֆի ստուգումն ապրում էր միայն իմ լոկալ pre-push սկրիպտում, ինչը նշանակում է՝ քշվում էր, երբ ես հիշում էի։ Հիմա այն քշվում է CI-ում, մեքենայի վրա, որն իմը չէ։
Ինչ չի նշանակում կանաչ CI-ն
Չի նշանակում, որ նախադասությունները ճիշտ են։ Մեր errata մատյանի ոչ մի գրառում gate-ը չի բռնել։
Ամենապարզ դեպքը Gemma-ի control-success claim-ն է։ Նրա ձևակերպումն ասում էր՝ «ընդունել է պատասխանի բացակայությունը՝ հորինելու փոխարեն»։ Արխիվային հարցում առ հարցում գրառումները ցույց են տալիս, որ ձախողված կոնտրոլները դատարկ պատասխաններ էին. reasoning-անցումը կերել էր թոքեն-բյուջեն, նախքան որևէ տեքստ դուրս կգար։ Ոչ մի գործարկում կոդ չէր հորինել։ Արժեքը տեղից չշարժվեց։ Նրա շուրջ ձևակերպումն էր սխալ, և սխալ՝ ի վնաս մոդելի, իսկ խողովակաշարը դա տեսնել չէր կարող, որովհետև ստուգում է թվաբանությունը, իսկ սխալն անգլերենի մեջ էր։ Ուղղումն errata-ի գրառում էր և վերաձևակերպում՝ երկու կողմից իրար հղված։ Մինչ ես սա գրում եմ, այդ արժեքը հաշվող SQL ֆայլի վերևի մեկնաբանությունը դեռ ասում է «հորինելու փոխարեն»։ CI-ն մեկնաբանություններ էլ չի կարդում։
Հետո՝ երկար կոնտեքստի սանդուղքը, որի նոմինալ թոքեն-քանակները գալիս էին «նիշ մեկ թոքենի» գնահատականից։ Runtime-ի սեփական հաշվառմամբ չափելիս անգլերեն աստիճանները նոմինալին մոտ նստեցին, ռուսերենները՝ դրանից շատ ցածր։ Կորպուսի բայթերն անձեռնմխելի էին և դեռ համընկնում էին իրենց սառեցված հեշի հետ։ Սխալն ապացույցի նկարագրության մեջ էր, ոչ թե ապացույցի, և հեշը դա տեսնել չի կարող։ Բռնվեց նորից կարդալիս; ամեն տարրի չափված քանակները հիմա դրված են կորպուսի կողքին։
Հետո՝ մեկ բառ. կայքի տեքստն ասում էր «նախագրանցված», նախքան նախագրանցման որևէ արտեֆակտ սառեցված կլիներ։ Վերաձևակերպվեց ռեվյուից հետո։
Եվ ևս մեկը։ Այն առավոտ, երբ դրեյֆի gate-ը տեղափոխվեց հեռավոր մեքենա, errata էջը թարմացվեց՝ ասելով, որ ուղղումների կարիք դեռ չի եղել։ Նախադասությունն ապրեց մեկ առավոտվա մի մասը։ Բացահայտումների էջն օրեր շարունակ ասում էր, թե ոչ մի ուղղում չի արձանագրվել, մինչդեռ մատյանում արդեն մի քանիսը կար։ Ուղղումների մասին էջն ինքն ուղղման կարիք ուներ։
Gate-ը ստուգում է թվաբանությունը թվի և նրա նշած գործարկումների միջև, ուրիշ ոչինչ, և ես, միևնույն է, նորից այն կկառուցեի։ Թվաբանությունն այն մասն է, որ խմբագրվում է լուռ, կեսգիշերին, երբ մեկ գործարկում դուրս գցելիս արդյունքն ավելի լավ տեսք է ստանում, և ոչ ոք չէր նկատի։ Նախադասությունները խմբագրվում են ցերեկով, բոլորի աչքի առաջ, և միևնույն է՝ սխալ են դուրս գալիս։ Թվերի պահակը սկրիպտ է, որին ոչ մի բանում համոզել չես կարող։ Նախադասությունների պահակն ես եմ, իսկ ինձ՝ կարող ես։