instar 1.3.462 → 1.3.464
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +43 -2
- package/dist/commands/server.js.map +1 -1
- package/dist/config/ConfigDefaults.d.ts.map +1 -1
- package/dist/config/ConfigDefaults.js +10 -0
- package/dist/config/ConfigDefaults.js.map +1 -1
- package/dist/core/types.d.ts +10 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/feedback-factory/cutoverReadiness.d.ts +34 -0
- package/dist/feedback-factory/cutoverReadiness.d.ts.map +1 -1
- package/dist/feedback-factory/cutoverReadiness.js +37 -0
- package/dist/feedback-factory/cutoverReadiness.js.map +1 -1
- package/dist/feedback-factory/migration/PersistedShadowImportTarget.d.ts +54 -0
- package/dist/feedback-factory/migration/PersistedShadowImportTarget.d.ts.map +1 -0
- package/dist/feedback-factory/migration/PersistedShadowImportTarget.js +121 -0
- package/dist/feedback-factory/migration/PersistedShadowImportTarget.js.map +1 -0
- package/dist/feedback-factory/migration/integrityPassRunner.d.ts +26 -0
- package/dist/feedback-factory/migration/integrityPassRunner.d.ts.map +1 -0
- package/dist/feedback-factory/migration/integrityPassRunner.js +83 -0
- package/dist/feedback-factory/migration/integrityPassRunner.js.map +1 -0
- package/dist/monitoring/ActiveWorkSilenceSentinel.d.ts +27 -2
- package/dist/monitoring/ActiveWorkSilenceSentinel.d.ts.map +1 -1
- package/dist/monitoring/ActiveWorkSilenceSentinel.js +50 -0
- package/dist/monitoring/ActiveWorkSilenceSentinel.js.map +1 -1
- package/dist/monitoring/SentinelNotifier.d.ts +1 -1
- package/dist/monitoring/SentinelNotifier.d.ts.map +1 -1
- package/dist/monitoring/SentinelNotifier.js.map +1 -1
- package/dist/monitoring/sentinelWiring.d.ts +8 -0
- package/dist/monitoring/sentinelWiring.d.ts.map +1 -1
- package/dist/monitoring/sentinelWiring.js +10 -0
- package/dist/monitoring/sentinelWiring.js.map +1 -1
- package/dist/server/AgentServer.d.ts.map +1 -1
- package/dist/server/AgentServer.js +49 -0
- package/dist/server/AgentServer.js.map +1 -1
- package/dist/server/CapabilityIndex.d.ts.map +1 -1
- package/dist/server/CapabilityIndex.js +1 -0
- package/dist/server/CapabilityIndex.js.map +1 -1
- package/dist/server/middleware.d.ts.map +1 -1
- package/dist/server/middleware.js +3 -0
- package/dist/server/middleware.js.map +1 -1
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +28 -0
- package/dist/server/routes.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +47 -47
- package/upgrades/1.3.463.md +27 -0
- package/upgrades/1.3.464.md +72 -0
- package/upgrades/eli16/integrity-leg-shadow-import.md +27 -0
- package/upgrades/side-effects/autoheal-silence-ladder.md +98 -0
- package/upgrades/side-effects/integrity-leg-shadow-import.md +35 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cutoverReadiness.js","sourceRoot":"","sources":["../../src/feedback-factory/cutoverReadiness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"cutoverReadiness.js","sourceRoot":"","sources":["../../src/feedback-factory/cutoverReadiness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAqH7B,MAAM,6BAA6B,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AACzD;gFACgF;AAChF,MAAM,yBAAyB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAajD,MAAM,OAAO,gBAAgB;IACV,CAAC,CAAuB;IACxB,UAAU,CAAS;IACnB,cAAc,CAAS;IACxC;;;;;;;;;OASG;IACK,iBAAiB,GAA0F,IAAI,CAAC;IAExH,YAAY,IAA0B;QACpC,IAAI,IAAI,CAAC,sBAAsB,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,sBAAsB,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,EAAE,CAAC;YACxH,sEAAsE;YACtE,6EAA6E;YAC7E,MAAM,IAAI,KAAK,CAAC,6GAA6G,CAAC,CAAC;QACjI,CAAC;QACD,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;QACd,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,kBAAkB,IAAI,6BAA6B,CAAC;QAC3E,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,IAAI,yBAAyB,CAAC;IACzE,CAAC;IAEO,KAAK;QACX,OAAO,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;IAChD,CAAC;IAED;;;;;;;+DAO2D;IACnD,KAAK,CAAC,WAAW,CAAI,IAAgB,EAAE,EAAU;QACvD,IAAI,KAAgD,CAAC;QACrD,MAAM,KAAK,GAAG,IAAI,OAAO,CAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE;YACpD,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;gBACtB,MAAM,CAAC,IAAI,KAAK,CACd,QAAQ,EAAE,wCAAwC,IAAI,CAAC,cAAc,iIAAiI,CACvM,CAAC,CAAC;YACL,CAAC,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;YACxB,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,UAAU;gBAAE,KAAK,CAAC,KAAK,EAAE,CAAC;QACvD,CAAC,CAAC,CAAC;QACH,IAAI,CAAC;YACH,OAAO,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;QAC3C,CAAC;gBAAS,CAAC;YACT,IAAI,KAAK;gBAAE,YAAY,CAAC,KAAK,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IAED,2EAA2E;IAC3E,qBAAqB,CAAC,MAAuB,EAAE,WAAoB;QACjE,MAAM,QAAQ,GAA+B;YAC3C,WAAW,EAAE,WAAW,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,WAAW,EAAE;YAChE,MAAM;SACP,CAAC;QACF,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,mBAAmB,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5E,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,mBAAmB,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAClF,CAAC;IAED,eAAe;QACb,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAA+B,CAAC;YAC1G,MAAM,CAAC,GAAG,GAAG,EAAE,MAAM,CAAC;YACtB,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBACxC,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;YACzE,CAAC;YACD,OAAO;gBACL,GAAG,EAAE,IAAI;gBACT,MAAM,EAAE,CAAC,CAAC,MAAM;gBAChB,WAAW,EAAE,OAAO,GAAG,CAAC,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI;gBACzE,OAAO,EAAE;oBACP,qBAAqB,EAAE,CAAC,CAAC,qBAAqB,EAAE,MAAM,IAAI,CAAC;oBAC3D,iBAAiB,EAAE,CAAC,CAAC,iBAAiB,EAAE,MAAM,IAAI,CAAC;oBACnD,kBAAkB,EAAE,CAAC,CAAC,kBAAkB,EAAE,MAAM,IAAI,CAAC;oBACrD,YAAY,EAAE,CAAC,CAAC,YAAY,EAAE,MAAM,IAAI,CAAC;iBAC1C;aACF,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC,CAAC,4FAA4F;YACpG,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QACzE,CAAC;IACH,CAAC;IAED,YAAY;QACV,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;QACpD,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC;QAC3C,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QAC3E,MAAM,KAAK,GAAG,UAAU,KAAK,IAAI;YAC/B,CAAC,CAAC,IAAI;YACN,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC;QAC5D,OAAO,EAAE,GAAG,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;IACxC,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,aAAa;QACjB,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,cAAc,EAAE,CAAC;YAC3B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,wFAAwF,EAAE,CAAC;QACzH,CAAC;QACD,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC3B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,wCAAwC,IAAI,CAAC,iBAAiB,CAAC,EAAE,YAAY,IAAI,CAAC,iBAAiB,CAAC,SAAS,6CAA6C,EAAE,CAAC;QAC3L,CAAC;QACD,IAAI,CAAC,iBAAiB,GAAG,EAAE,EAAE,EAAE,aAAa,EAAE,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;QAChG,IAAI,MAAoB,CAAC;QACzB,IAAI,CAAC;YACH,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,cAAc,EAAE,EAAE,aAAa,CAAC,CAAC;QAC1E,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,wBAAwB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QAC3G,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;QAChC,CAAC;QACD,MAAM,EAAE,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;QAChD,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,YAAY,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAC9C,MAAM,WAAW,GAAG,MAAM,CAAC,sBAAsB,CAAC,MAAM,GAAG,MAAM,CAAC,kBAAkB,CAAC,MAAM,CAAC;QAC5F,OAAO;YACL,EAAE,EAAE,IAAI;YACR,IAAI,EAAE,EAAE,EAAE,EAAE,gBAAgB,EAAE,MAAM,CAAC,gBAAgB,EAAE,WAAW,EAAE,SAAS,EAAE,WAAW,GAAG,CAAC,EAAE;YAChG,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;SACpC,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,mBAAmB;QACvB,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,eAAe,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,sBAAsB,EAAE,CAAC;YAC9D,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,6FAA6F,EAAE,CAAC;QAC9H,CAAC;QACD,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC3B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,wCAAwC,IAAI,CAAC,iBAAiB,CAAC,EAAE,YAAY,IAAI,CAAC,iBAAiB,CAAC,SAAS,6CAA6C,EAAE,CAAC;QAC3L,CAAC;QACD,IAAI,CAAC,iBAAiB,GAAG,EAAE,EAAE,EAAE,gBAAgB,EAAE,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;QACnG,IAAI,MAAuB,CAAC;QAC5B,IAAI,CAAC;YACH,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,eAAe,EAAE,EAAE,gBAAgB,CAAC,CAAC;QAC9E,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,0BAA0B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QAC7G,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;QAChC,CAAC;QACD,MAAM,WAAW,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;QACzD,MAAM,QAAQ,GAA4B,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;QACnF,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,sBAAsB,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/E,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,sBAAsB,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACnF,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IAC3C,CAAC;IAED;;;;;;;;;;OAUG;IACH,KAAK,CAAC,gBAAgB;QACpB,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,kBAAkB,EAAE,CAAC;YAC/B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,iGAAiG,EAAE,CAAC;QAClI,CAAC;QACD,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC3B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,wCAAwC,IAAI,CAAC,iBAAiB,CAAC,EAAE,YAAY,IAAI,CAAC,iBAAiB,CAAC,SAAS,6CAA6C,EAAE,CAAC;QAC3L,CAAC;QACD,IAAI,CAAC,iBAAiB,GAAG,EAAE,EAAE,EAAE,gBAAgB,EAAE,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;QACnG,IAAI,MAAuB,CAAC;QAC5B,IAAI,CAAC;YACH,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,kBAAkB,EAAE,EAAE,gBAAgB,CAAC,CAAC;QACjF,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,0BAA0B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QAC7G,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;QAChC,CAAC;QACD,MAAM,WAAW,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;QACzD,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAClB,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;YACvD,QAAQ,GAAG,IAAI,CAAC;QAClB,CAAC;QACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC;IACrD,CAAC;IAED,kBAAkB;QAChB,MAAM,KAAK,GAAuB,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAC;QAC3H,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,sBAAsB;YAAE,OAAO,KAAK,CAAC;QACjD,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,sBAAsB,EAAE,MAAM,CAAC,CAA4B,CAAC;YAC1G,MAAM,CAAC,GAAG,GAAG,EAAE,MAAM,CAAC;YACtB,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,SAAS;gBAAE,OAAO,KAAK,CAAC;YACtD,OAAO;gBACL,GAAG,EAAE,IAAI;gBACT,MAAM,EAAE,CAAC,CAAC,MAAM;gBAChB,WAAW,EAAE,OAAO,GAAG,CAAC,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI;gBACzE,QAAQ,EAAE,CAAC,CAAC,QAAQ,IAAI,IAAI;gBAC5B,gBAAgB,EAAE,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI;aACxE,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC,CAAC,8GAA8G;YACtH,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,uFAAuF;IACvF,MAAM;QACJ,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;QACzC,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QACnC,OAAO;YACL,0FAA0F;YAC1F,KAAK,EAAE,SAAS,CAAC,MAAM,IAAI,MAAM,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK;YAC1D,IAAI,EAAE,uBAAuB;YAC7B,SAAS;YACT,MAAM;YACN,YAAY,EAAE,IAAI,CAAC,kBAAkB,EAAE;SACxC,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PersistedShadowImportTarget.ts — a DURABLE, on-disk AS-IS import sink for the
|
|
3
|
+
* pre-click cutover integrity gate (spec §2.4; feedback-factory-migration.md §2.5).
|
|
4
|
+
*
|
|
5
|
+
* Why this exists (and why it is NOT `InMemoryImportTarget`):
|
|
6
|
+
*
|
|
7
|
+
* `cutoverReadiness.ts` hard-gates the operator's IRREVERSIBLE cutover click on
|
|
8
|
+
* `ready = integrity.passed && parity.cleared && !parity.stale`. The integrity leg
|
|
9
|
+
* greens ONLY when `recordIntegrityReport(passingReport)` is called. The existing
|
|
10
|
+
* import-DRYRUN route is deliberately walled off from that path (its report goes to
|
|
11
|
+
* `importDryRunReportPath`, never `integrityReportPath`) precisely so an EPHEMERAL,
|
|
12
|
+
* in-memory rehearsal can never quietly green an irreversible gate.
|
|
13
|
+
*
|
|
14
|
+
* The pre-click integrity gate therefore needs a target that is a step more real than
|
|
15
|
+
* the in-memory dry-run: a **persisted** shadow the import physically lands in and is
|
|
16
|
+
* read back FROM DISK, so the recorded integrity report corresponds to a durable,
|
|
17
|
+
* inspectable artifact — not an in-process Map that vanishes with the process. The
|
|
18
|
+
* shadow is a VERIFICATION target, never canonical: the canonical production import
|
|
19
|
+
* (Portal's apply-clusters / the real Prisma write) happens AFTER the click. This
|
|
20
|
+
* mirrors `InMemoryImportTarget`'s contract exactly (same `ImportTarget` interface,
|
|
21
|
+
* same dup-PK refusal, same `schemaDescriptor() === null` → the runner derives the
|
|
22
|
+
* dry-run schema), differing ONLY in where the rows live.
|
|
23
|
+
*
|
|
24
|
+
* Backing store: two newline-delimited JSON files (`clusters.jsonl`, `feedback.jsonl`)
|
|
25
|
+
* under a caller-supplied directory. JSONL (not SQLite) keeps the target dependency-free
|
|
26
|
+
* so the out-of-process integrity-pass runner bundles cleanly (no native module). Each
|
|
27
|
+
* AS-IS import APPENDS one row; `readBack*` parses the file. Duplicate PKs are refused
|
|
28
|
+
* before the append (mirrors the DB @id constraint the real adapter would hit). The
|
|
29
|
+
* shadow directory is disposable — `dispose()` removes it after the gate has run.
|
|
30
|
+
*/
|
|
31
|
+
import { type ImportTarget, type RawRow } from './importRunner.js';
|
|
32
|
+
import type { SchemaDescriptor } from './importIntegrity.js';
|
|
33
|
+
export declare class PersistedShadowImportTarget implements ImportTarget {
|
|
34
|
+
private readonly dir;
|
|
35
|
+
private readonly clustersPath;
|
|
36
|
+
private readonly feedbackPath;
|
|
37
|
+
private readonly clusterIds;
|
|
38
|
+
private readonly feedbackIds;
|
|
39
|
+
constructor(dir: string);
|
|
40
|
+
private readJsonl;
|
|
41
|
+
importClusterAsIs(row: RawRow): void;
|
|
42
|
+
importFeedbackAsIs(row: RawRow): void;
|
|
43
|
+
readBackClusters(): RawRow[];
|
|
44
|
+
readBackFeedback(): RawRow[];
|
|
45
|
+
/**
|
|
46
|
+
* No real schema descriptor — like the in-memory dry-run target, the runner derives
|
|
47
|
+
* the target schema from readback + the canonical accepted-status contract. (A future
|
|
48
|
+
* real Prisma adapter would return its actual descriptor here.)
|
|
49
|
+
*/
|
|
50
|
+
schemaDescriptor(): SchemaDescriptor | null;
|
|
51
|
+
/** Remove the on-disk shadow. Call after the integrity gate has run + the report is recorded. */
|
|
52
|
+
dispose(): void;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=PersistedShadowImportTarget.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PersistedShadowImportTarget.d.ts","sourceRoot":"","sources":["../../../src/feedback-factory/migration/PersistedShadowImportTarget.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAIH,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,MAAM,EAEZ,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAa7D,qBAAa,2BAA4B,YAAW,YAAY;IASlD,OAAO,CAAC,QAAQ,CAAC,GAAG;IARhC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IAItC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAqB;IAChD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;gBAEpB,GAAG,EAAE,MAAM;IAexC,OAAO,CAAC,SAAS;IAWjB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAQpC,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAQrC,gBAAgB,IAAI,MAAM,EAAE;IAI5B,gBAAgB,IAAI,MAAM,EAAE;IAI5B;;;;OAIG;IACH,gBAAgB,IAAI,gBAAgB,GAAG,IAAI;IAI3C,iGAAiG;IACjG,OAAO,IAAI,IAAI;CAGhB"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PersistedShadowImportTarget.ts — a DURABLE, on-disk AS-IS import sink for the
|
|
3
|
+
* pre-click cutover integrity gate (spec §2.4; feedback-factory-migration.md §2.5).
|
|
4
|
+
*
|
|
5
|
+
* Why this exists (and why it is NOT `InMemoryImportTarget`):
|
|
6
|
+
*
|
|
7
|
+
* `cutoverReadiness.ts` hard-gates the operator's IRREVERSIBLE cutover click on
|
|
8
|
+
* `ready = integrity.passed && parity.cleared && !parity.stale`. The integrity leg
|
|
9
|
+
* greens ONLY when `recordIntegrityReport(passingReport)` is called. The existing
|
|
10
|
+
* import-DRYRUN route is deliberately walled off from that path (its report goes to
|
|
11
|
+
* `importDryRunReportPath`, never `integrityReportPath`) precisely so an EPHEMERAL,
|
|
12
|
+
* in-memory rehearsal can never quietly green an irreversible gate.
|
|
13
|
+
*
|
|
14
|
+
* The pre-click integrity gate therefore needs a target that is a step more real than
|
|
15
|
+
* the in-memory dry-run: a **persisted** shadow the import physically lands in and is
|
|
16
|
+
* read back FROM DISK, so the recorded integrity report corresponds to a durable,
|
|
17
|
+
* inspectable artifact — not an in-process Map that vanishes with the process. The
|
|
18
|
+
* shadow is a VERIFICATION target, never canonical: the canonical production import
|
|
19
|
+
* (Portal's apply-clusters / the real Prisma write) happens AFTER the click. This
|
|
20
|
+
* mirrors `InMemoryImportTarget`'s contract exactly (same `ImportTarget` interface,
|
|
21
|
+
* same dup-PK refusal, same `schemaDescriptor() === null` → the runner derives the
|
|
22
|
+
* dry-run schema), differing ONLY in where the rows live.
|
|
23
|
+
*
|
|
24
|
+
* Backing store: two newline-delimited JSON files (`clusters.jsonl`, `feedback.jsonl`)
|
|
25
|
+
* under a caller-supplied directory. JSONL (not SQLite) keeps the target dependency-free
|
|
26
|
+
* so the out-of-process integrity-pass runner bundles cleanly (no native module). Each
|
|
27
|
+
* AS-IS import APPENDS one row; `readBack*` parses the file. Duplicate PKs are refused
|
|
28
|
+
* before the append (mirrors the DB @id constraint the real adapter would hit). The
|
|
29
|
+
* shadow directory is disposable — `dispose()` removes it after the gate has run.
|
|
30
|
+
*/
|
|
31
|
+
import { appendFileSync, mkdirSync, readFileSync, existsSync } from 'node:fs';
|
|
32
|
+
import { join } from 'node:path';
|
|
33
|
+
import { DuplicateImportIdError, } from './importRunner.js';
|
|
34
|
+
import { SafeFsExecutor } from '../../core/SafeFsExecutor.js';
|
|
35
|
+
/** Resolve a row's primary-key id from the AS-IS field aliases (mirrors importRunner's pickId). */
|
|
36
|
+
function pickId(row, ...keys) {
|
|
37
|
+
for (const k of keys) {
|
|
38
|
+
const v = row[k];
|
|
39
|
+
if (typeof v === 'string' && v.length > 0)
|
|
40
|
+
return v;
|
|
41
|
+
if (typeof v === 'number')
|
|
42
|
+
return String(v);
|
|
43
|
+
}
|
|
44
|
+
return '';
|
|
45
|
+
}
|
|
46
|
+
export class PersistedShadowImportTarget {
|
|
47
|
+
dir;
|
|
48
|
+
clustersPath;
|
|
49
|
+
feedbackPath;
|
|
50
|
+
// In-memory PK sets enforce the @id constraint at import time (the durable readback
|
|
51
|
+
// is still the file). Sets are rebuilt from disk on construction so a reused dir is
|
|
52
|
+
// duplicate-safe across processes.
|
|
53
|
+
clusterIds = new Set();
|
|
54
|
+
feedbackIds = new Set();
|
|
55
|
+
constructor(dir) {
|
|
56
|
+
this.dir = dir;
|
|
57
|
+
mkdirSync(dir, { recursive: true });
|
|
58
|
+
this.clustersPath = join(dir, 'clusters.jsonl');
|
|
59
|
+
this.feedbackPath = join(dir, 'feedback.jsonl');
|
|
60
|
+
// Rebuild PK sets from any rows already on disk (idempotent reuse / crash recovery).
|
|
61
|
+
for (const r of this.readJsonl(this.clustersPath)) {
|
|
62
|
+
const id = pickId(r, 'clusterId', 'cluster_id', 'id');
|
|
63
|
+
if (id)
|
|
64
|
+
this.clusterIds.add(id);
|
|
65
|
+
}
|
|
66
|
+
for (const r of this.readJsonl(this.feedbackPath)) {
|
|
67
|
+
const id = pickId(r, 'feedbackId', 'feedback_id', 'id');
|
|
68
|
+
if (id)
|
|
69
|
+
this.feedbackIds.add(id);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
readJsonl(path) {
|
|
73
|
+
if (!existsSync(path))
|
|
74
|
+
return [];
|
|
75
|
+
const txt = readFileSync(path, 'utf8');
|
|
76
|
+
const out = [];
|
|
77
|
+
for (const line of txt.split('\n')) {
|
|
78
|
+
if (!line)
|
|
79
|
+
continue;
|
|
80
|
+
out.push(JSON.parse(line));
|
|
81
|
+
}
|
|
82
|
+
return out;
|
|
83
|
+
}
|
|
84
|
+
importClusterAsIs(row) {
|
|
85
|
+
const id = pickId(row, 'clusterId', 'cluster_id', 'id');
|
|
86
|
+
if (!id)
|
|
87
|
+
throw new Error('cluster row has no resolvable id (clusterId/cluster_id/id) — cannot import');
|
|
88
|
+
if (this.clusterIds.has(id))
|
|
89
|
+
throw new DuplicateImportIdError('cluster', id);
|
|
90
|
+
this.clusterIds.add(id);
|
|
91
|
+
appendFileSync(this.clustersPath, JSON.stringify(row) + '\n');
|
|
92
|
+
}
|
|
93
|
+
importFeedbackAsIs(row) {
|
|
94
|
+
const id = pickId(row, 'feedbackId', 'feedback_id', 'id');
|
|
95
|
+
if (!id)
|
|
96
|
+
throw new Error('feedback row has no resolvable id (feedbackId/feedback_id/id) — cannot import');
|
|
97
|
+
if (this.feedbackIds.has(id))
|
|
98
|
+
throw new DuplicateImportIdError('feedback', id);
|
|
99
|
+
this.feedbackIds.add(id);
|
|
100
|
+
appendFileSync(this.feedbackPath, JSON.stringify(row) + '\n');
|
|
101
|
+
}
|
|
102
|
+
readBackClusters() {
|
|
103
|
+
return this.readJsonl(this.clustersPath);
|
|
104
|
+
}
|
|
105
|
+
readBackFeedback() {
|
|
106
|
+
return this.readJsonl(this.feedbackPath);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* No real schema descriptor — like the in-memory dry-run target, the runner derives
|
|
110
|
+
* the target schema from readback + the canonical accepted-status contract. (A future
|
|
111
|
+
* real Prisma adapter would return its actual descriptor here.)
|
|
112
|
+
*/
|
|
113
|
+
schemaDescriptor() {
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
/** Remove the on-disk shadow. Call after the integrity gate has run + the report is recorded. */
|
|
117
|
+
dispose() {
|
|
118
|
+
SafeFsExecutor.safeRmSync(this.dir, { recursive: true, force: true, operation: 'PersistedShadowImportTarget.dispose' });
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=PersistedShadowImportTarget.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PersistedShadowImportTarget.js","sourceRoot":"","sources":["../../../src/feedback-factory/migration/PersistedShadowImportTarget.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type ImportRunResult } from './importRunner.js';
|
|
2
|
+
/** What the pass returns (and prints as stdout JSON in CLI mode). */
|
|
3
|
+
export interface IntegrityPassResult {
|
|
4
|
+
passed: boolean;
|
|
5
|
+
imported: ImportRunResult['imported'];
|
|
6
|
+
abortedPreImport: ImportRunResult['abortedPreImport'];
|
|
7
|
+
report: ImportRunResult['report'];
|
|
8
|
+
fetchSeconds: number;
|
|
9
|
+
importSeconds: number;
|
|
10
|
+
}
|
|
11
|
+
/** The minimal source contract the pass consumes — lets tests inject a fake. */
|
|
12
|
+
export interface RawCorpusSource {
|
|
13
|
+
prepare(): Promise<void>;
|
|
14
|
+
readRawClusters(): Record<string, unknown>[];
|
|
15
|
+
readRawFeedback(): Record<string, unknown>[];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Run the AS-IS import of `source`'s corpus into a persisted shadow under `shadowDir`,
|
|
19
|
+
* then the integrity gate over the readback. The shadow dir is removed afterward unless
|
|
20
|
+
* `keepShadow`. Pure w.r.t. canonical state — the shadow is a verification target only.
|
|
21
|
+
*/
|
|
22
|
+
export declare function runIntegrityPass(source: RawCorpusSource, shadowDir: string, opts?: {
|
|
23
|
+
keepShadow?: boolean;
|
|
24
|
+
now?: () => number;
|
|
25
|
+
}): Promise<IntegrityPassResult>;
|
|
26
|
+
//# sourceMappingURL=integrityPassRunner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integrityPassRunner.d.ts","sourceRoot":"","sources":["../../../src/feedback-factory/migration/integrityPassRunner.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAa,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAIpE,qEAAqE;AACrE,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,eAAe,CAAC,UAAU,CAAC,CAAC;IACtC,gBAAgB,EAAE,eAAe,CAAC,kBAAkB,CAAC,CAAC;IACtD,MAAM,EAAE,eAAe,CAAC,QAAQ,CAAC,CAAC;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,gFAAgF;AAChF,MAAM,WAAW,eAAe;IAC9B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,eAAe,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IAC7C,eAAe,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;CAC9C;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,eAAe,EACvB,SAAS,EAAE,MAAM,EACjB,IAAI,GAAE;IAAE,UAAU,CAAC,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CAAO,GACtD,OAAO,CAAC,mBAAmB,CAAC,CAsB9B"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* integrityPassRunner.ts — the REAL pre-click import-integrity pass that greens the
|
|
3
|
+
* cutover door's INTEGRITY leg (spec §2.4; feedback-factory-migration.md §2.5).
|
|
4
|
+
*
|
|
5
|
+
* Runs the canonical pipeline — HttpParitySource captureRaw (read-only GET
|
|
6
|
+
* /api/instar/read) → runImport into a PERSISTED shadow target → the pure integrity
|
|
7
|
+
* gate over the readback — and returns the IntegrityReport verdict. The caller
|
|
8
|
+
* (AgentServer) feeds a PASSING report to `CutoverReadiness.recordIntegrityReport()`.
|
|
9
|
+
*
|
|
10
|
+
* Why this is a standalone module with a CLI entry (not an in-process closure like
|
|
11
|
+
* runParityCheck): the full 145K-row captureRaw fetch + import cannot settle inside
|
|
12
|
+
* the server's single-flight budget when run IN the event loop — that is exactly why
|
|
13
|
+
* the in-process import-dryrun budget-fails at 720s (#948), and why the parity-pass
|
|
14
|
+
* had to drop to clustersOnly (#1007). The heavy pass belongs OFF the event loop, so
|
|
15
|
+
* AgentServer spawns this module as a child `node` process. Exporting the logic as a
|
|
16
|
+
* function ALSO keeps it unit-testable against an injected source.
|
|
17
|
+
*/
|
|
18
|
+
import { tmpdir } from 'node:os';
|
|
19
|
+
import { join, resolve } from 'node:path';
|
|
20
|
+
import { fileURLToPath } from 'node:url';
|
|
21
|
+
import { runImport } from './importRunner.js';
|
|
22
|
+
import { PersistedShadowImportTarget } from './PersistedShadowImportTarget.js';
|
|
23
|
+
import { HttpParitySource } from '../dryrun/HttpParitySource.js';
|
|
24
|
+
/**
|
|
25
|
+
* Run the AS-IS import of `source`'s corpus into a persisted shadow under `shadowDir`,
|
|
26
|
+
* then the integrity gate over the readback. The shadow dir is removed afterward unless
|
|
27
|
+
* `keepShadow`. Pure w.r.t. canonical state — the shadow is a verification target only.
|
|
28
|
+
*/
|
|
29
|
+
export async function runIntegrityPass(source, shadowDir, opts = {}) {
|
|
30
|
+
const now = opts.now ?? (() => Date.now());
|
|
31
|
+
const t0 = now();
|
|
32
|
+
const target = new PersistedShadowImportTarget(shadowDir);
|
|
33
|
+
try {
|
|
34
|
+
await source.prepare();
|
|
35
|
+
const clusters = source.readRawClusters();
|
|
36
|
+
const feedback = source.readRawFeedback();
|
|
37
|
+
const tFetch = now();
|
|
38
|
+
const result = runImport({ clusters, feedback }, target);
|
|
39
|
+
const tDone = now();
|
|
40
|
+
return {
|
|
41
|
+
passed: result.passed,
|
|
42
|
+
imported: result.imported,
|
|
43
|
+
abortedPreImport: result.abortedPreImport,
|
|
44
|
+
report: result.report,
|
|
45
|
+
fetchSeconds: Number(((tFetch - t0) / 1000).toFixed(1)),
|
|
46
|
+
importSeconds: Number(((tDone - tFetch) / 1000).toFixed(1)),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
finally {
|
|
50
|
+
if (!opts.keepShadow)
|
|
51
|
+
target.dispose();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/** CLI entry: env-driven, prints the verdict JSON to stdout. Used by AgentServer's child spawn. */
|
|
55
|
+
async function main() {
|
|
56
|
+
const token = process.env.TOKEN;
|
|
57
|
+
if (!token) {
|
|
58
|
+
console.error('FATAL: TOKEN env required (instar:read scope)');
|
|
59
|
+
process.exit(2);
|
|
60
|
+
}
|
|
61
|
+
const baseUrl = process.env.BASE_URL || 'https://dawn.bot-me.ai';
|
|
62
|
+
const shadowDir = process.env.SHADOW_DIR || join(tmpdir(), `cutover-integrity-shadow-${process.pid}`);
|
|
63
|
+
const keepShadow = process.env.KEEP_SHADOW === '1';
|
|
64
|
+
const source = new HttpParitySource({
|
|
65
|
+
baseUrl,
|
|
66
|
+
token,
|
|
67
|
+
captureRaw: true,
|
|
68
|
+
pageTimeoutMs: 120_000,
|
|
69
|
+
// Stay UNDER CutoverReadiness's 12-min single-flight max-hold backstop so the
|
|
70
|
+
// child self-exits before the in-process guard fires (measured pass ~2.7min).
|
|
71
|
+
totalTimeoutMs: 600_000,
|
|
72
|
+
});
|
|
73
|
+
console.error(`[integrity-pass] fetching corpus from ${baseUrl}/api/instar/read (captureRaw) → shadow ${shadowDir} ...`);
|
|
74
|
+
const out = await runIntegrityPass(source, shadowDir, { keepShadow });
|
|
75
|
+
console.error(`[integrity-pass] fetch ${out.fetchSeconds}s + import/integrity ${out.importSeconds}s → passed=${out.passed}`);
|
|
76
|
+
console.log(JSON.stringify(out));
|
|
77
|
+
process.exit(out.passed ? 0 : 1);
|
|
78
|
+
}
|
|
79
|
+
// Direct-run detection (ESM): run main() only when invoked as a script, not when imported.
|
|
80
|
+
if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
|
|
81
|
+
void main();
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=integrityPassRunner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integrityPassRunner.js","sourceRoot":"","sources":["../../../src/feedback-factory/migration/integrityPassRunner.ts"],"names":[],"mappings":"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"}
|
|
@@ -23,13 +23,16 @@
|
|
|
23
23
|
* via the notify path. No new blocking authority.
|
|
24
24
|
*/
|
|
25
25
|
import { EventEmitter } from 'node:events';
|
|
26
|
-
export type SilenceStatus = 'detected' | 'nudged' | 'recovered' | 'escalated';
|
|
26
|
+
export type SilenceStatus = 'detected' | 'nudged' | 'recovered' | 'recovering' | 'recovery-failed' | 'escalated';
|
|
27
27
|
export interface SilenceState {
|
|
28
28
|
sessionName: string;
|
|
29
29
|
detectedAt: number;
|
|
30
30
|
lastOutputAtAtDetection: number;
|
|
31
31
|
nudgedAt: number;
|
|
32
32
|
status: SilenceStatus;
|
|
33
|
+
/** Auto-recovery (respawn) attempts made for this stall episode. Bounded by
|
|
34
|
+
* maxAutoRecoveries to prevent a respawn-loop on a session that stays stuck. */
|
|
35
|
+
recoveryAttempts: number;
|
|
33
36
|
}
|
|
34
37
|
export interface SessionRegistryEntry {
|
|
35
38
|
sessionName: string;
|
|
@@ -45,8 +48,15 @@ export interface ActiveWorkSilenceSentinelDeps {
|
|
|
45
48
|
listSessions: () => SessionRegistryEntry[];
|
|
46
49
|
/** Send an empty send-keys to wake the pane. Returns whether it was accepted. */
|
|
47
50
|
nudgeFn: (sessionName: string) => Promise<boolean>;
|
|
48
|
-
/** Route a user-facing message; server.ts owns topic routing
|
|
51
|
+
/** Route a user-facing message; server.ts owns topic routing (→ the stalled
|
|
52
|
+
* session's OWN topic when auto-recover is on). */
|
|
49
53
|
notifyFn: (sessionName: string, text: string) => Promise<void>;
|
|
54
|
+
/** Auto-recovery primitive: fresh-respawn a confirmed-stuck session
|
|
55
|
+
* (conversation preserved via resume/bootstrap). Returns whether it succeeded.
|
|
56
|
+
* Optional — when absent (or autoRecover off) the sentinel falls back to the
|
|
57
|
+
* ask-the-user escalation. DESTRUCTIVE (discards in-context work), so it only
|
|
58
|
+
* runs after the nudge fails AND is bounded by maxAutoRecoveries. */
|
|
59
|
+
recoverFn?: (sessionName: string) => Promise<boolean>;
|
|
50
60
|
/** Override Date.now for tests. */
|
|
51
61
|
now?: () => number;
|
|
52
62
|
/** Override timer setters for tests. */
|
|
@@ -61,6 +71,14 @@ export interface ActiveWorkSilenceSentinelConfig {
|
|
|
61
71
|
silenceThresholdMs?: number;
|
|
62
72
|
/** Verify window — how long after nudge before declaring escalate (ms). Default 30s. */
|
|
63
73
|
verifyWindowMs?: number;
|
|
74
|
+
/** Auto-recover (respawn) a stalled session after the nudge fails, instead of
|
|
75
|
+
* only asking the user. DARK by default — destructive (discards in-context
|
|
76
|
+
* work), so opt-in. When off, behaviour is unchanged (nudge → ask). */
|
|
77
|
+
autoRecover?: boolean;
|
|
78
|
+
/** Hard cap on auto-recovery (respawn) attempts per stall episode. Prevents a
|
|
79
|
+
* respawn-loop on a session that stays stuck after a respawn. Default 1 —
|
|
80
|
+
* one auto-respawn, then fall back to asking the user. */
|
|
81
|
+
maxAutoRecoveries?: number;
|
|
64
82
|
}
|
|
65
83
|
export declare class ActiveWorkSilenceSentinel extends EventEmitter {
|
|
66
84
|
private readonly deps;
|
|
@@ -81,6 +99,13 @@ export declare class ActiveWorkSilenceSentinel extends EventEmitter {
|
|
|
81
99
|
private runNudge;
|
|
82
100
|
private verifyNudge;
|
|
83
101
|
private escalate;
|
|
102
|
+
/**
|
|
103
|
+
* Auto-recovery ladder (dark by default): notify in the stalled session's own
|
|
104
|
+
* topic, respawn it, then notify the outcome. Bounded by maxAutoRecoveries
|
|
105
|
+
* (the recoveryAttempts increment + the escalate() guard) so a session that
|
|
106
|
+
* stays stuck after a respawn falls back to asking the user — never a loop.
|
|
107
|
+
*/
|
|
108
|
+
private runRecovery;
|
|
84
109
|
private notify;
|
|
85
110
|
private setTimer;
|
|
86
111
|
private clearTimer;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ActiveWorkSilenceSentinel.d.ts","sourceRoot":"","sources":["../../src/monitoring/ActiveWorkSilenceSentinel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,MAAM,aAAa,
|
|
1
|
+
{"version":3,"file":"ActiveWorkSilenceSentinel.d.ts","sourceRoot":"","sources":["../../src/monitoring/ActiveWorkSilenceSentinel.ts"],"names":[],"mappings":"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"}
|
|
@@ -28,6 +28,8 @@ const DEFAULT_CONFIG = {
|
|
|
28
28
|
tickIntervalMs: 60_000,
|
|
29
29
|
silenceThresholdMs: 15 * 60_000,
|
|
30
30
|
verifyWindowMs: 30_000,
|
|
31
|
+
autoRecover: false,
|
|
32
|
+
maxAutoRecoveries: 1,
|
|
31
33
|
};
|
|
32
34
|
export class ActiveWorkSilenceSentinel extends EventEmitter {
|
|
33
35
|
deps;
|
|
@@ -90,6 +92,7 @@ export class ActiveWorkSilenceSentinel extends EventEmitter {
|
|
|
90
92
|
lastOutputAtAtDetection: lastOutputAt,
|
|
91
93
|
nudgedAt: 0,
|
|
92
94
|
status: 'detected',
|
|
95
|
+
recoveryAttempts: 0,
|
|
93
96
|
};
|
|
94
97
|
this.states.set(sessionName, state);
|
|
95
98
|
this.emit('silence', { sessionName, idleMs: now - lastOutputAt });
|
|
@@ -155,11 +158,58 @@ export class ActiveWorkSilenceSentinel extends EventEmitter {
|
|
|
155
158
|
const state = this.states.get(sessionName);
|
|
156
159
|
if (!state)
|
|
157
160
|
return;
|
|
161
|
+
// Auto-heal path (dark by default): after the nudge failed, recover the
|
|
162
|
+
// session (respawn) instead of only asking the user — bounded by
|
|
163
|
+
// maxAutoRecoveries so a session that stays stuck can't trigger a
|
|
164
|
+
// respawn-loop. Falls through to the ask-path when off / cap reached / no
|
|
165
|
+
// recoverFn wired.
|
|
166
|
+
if (this.cfg.autoRecover && this.deps.recoverFn && state.recoveryAttempts < this.cfg.maxAutoRecoveries) {
|
|
167
|
+
void this.runRecovery(sessionName);
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
158
170
|
state.status = 'escalated';
|
|
159
171
|
const minutes = Math.max(1, Math.round(((this.deps.now ?? Date.now)() - state.lastOutputAtAtDetection) / 60_000));
|
|
160
172
|
void this.notify(sessionName, `${friendlyName(sessionName)} was working and went quiet about ${minutes} minutes ago. I tried a gentle nudge and nothing came back. Want me to dig in?`);
|
|
161
173
|
this.emit('escalated', sessionName);
|
|
162
174
|
}
|
|
175
|
+
/**
|
|
176
|
+
* Auto-recovery ladder (dark by default): notify in the stalled session's own
|
|
177
|
+
* topic, respawn it, then notify the outcome. Bounded by maxAutoRecoveries
|
|
178
|
+
* (the recoveryAttempts increment + the escalate() guard) so a session that
|
|
179
|
+
* stays stuck after a respawn falls back to asking the user — never a loop.
|
|
180
|
+
*/
|
|
181
|
+
async runRecovery(sessionName) {
|
|
182
|
+
const state = this.states.get(sessionName);
|
|
183
|
+
if (!state || !this.deps.recoverFn)
|
|
184
|
+
return;
|
|
185
|
+
state.status = 'recovering';
|
|
186
|
+
state.recoveryAttempts += 1;
|
|
187
|
+
const minutes = Math.max(1, Math.round(((this.deps.now ?? Date.now)() - state.lastOutputAtAtDetection) / 60_000));
|
|
188
|
+
await this.notify(sessionName, `${friendlyName(sessionName)} went quiet about ${minutes} minutes ago and a nudge didn't wake it — auto-recovering it now.`);
|
|
189
|
+
this.emit('recovering', sessionName);
|
|
190
|
+
let ok = false;
|
|
191
|
+
try {
|
|
192
|
+
ok = await this.deps.recoverFn(sessionName);
|
|
193
|
+
}
|
|
194
|
+
catch (err) {
|
|
195
|
+
this.emit('recover-error', { sessionName, err });
|
|
196
|
+
ok = false;
|
|
197
|
+
}
|
|
198
|
+
if (ok) {
|
|
199
|
+
state.status = 'recovered';
|
|
200
|
+
await this.notify(sessionName, `${friendlyName(sessionName)} was stuck — I recovered it (fresh restart, conversation preserved). It should pick back up now.`);
|
|
201
|
+
this.emit('recovered', sessionName);
|
|
202
|
+
// Clear so the freshly-respawned session is monitored anew. The respawn
|
|
203
|
+
// resets its output clock, so it won't immediately re-trigger.
|
|
204
|
+
this.clear(sessionName);
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
// Respawn failed — fall back to asking the user, and DO NOT clear (the
|
|
208
|
+
// persisted state stops tick() re-detecting → no auto-recovery loop).
|
|
209
|
+
state.status = 'recovery-failed';
|
|
210
|
+
await this.notify(sessionName, `${friendlyName(sessionName)} went quiet and I couldn't auto-recover it. Want me to dig in?`);
|
|
211
|
+
this.emit('recovery-failed', sessionName);
|
|
212
|
+
}
|
|
163
213
|
async notify(sessionName, text) {
|
|
164
214
|
try {
|
|
165
215
|
await this.deps.notifyFn(sessionName, text);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ActiveWorkSilenceSentinel.js","sourceRoot":"","sources":["../../src/monitoring/ActiveWorkSilenceSentinel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"ActiveWorkSilenceSentinel.js","sourceRoot":"","sources":["../../src/monitoring/ActiveWorkSilenceSentinel.ts"],"names":[],"mappings":"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"}
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
*
|
|
29
29
|
* Spec: docs/specs/silently-stopped-trio.md
|
|
30
30
|
*/
|
|
31
|
-
export type SentinelEventKind = 'detected' | 'nudged' | 'recovered' | 'escalated' | 'escalation-sent' | 'escalation-suppressed' | 'nudge-error' | 'recovery-error' | 'notify-error' | 'dry-run' | 'false-alarm';
|
|
31
|
+
export type SentinelEventKind = 'detected' | 'nudged' | 'recovered' | 'escalated' | 'escalation-sent' | 'escalation-suppressed' | 'nudge-error' | 'recovery-error' | 'notify-error' | 'recovering' | 'dry-run' | 'false-alarm';
|
|
32
32
|
export interface SentinelLogEntry {
|
|
33
33
|
ts: string;
|
|
34
34
|
kind: SentinelEventKind;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SentinelNotifier.d.ts","sourceRoot":"","sources":["../../src/monitoring/SentinelNotifier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,MAAM,MAAM,iBAAiB,GACzB,UAAU,GACV,QAAQ,GACR,WAAW,GACX,WAAW,GACX,iBAAiB,GACjB,uBAAuB,GACvB,aAAa,GACb,gBAAgB,GAChB,cAAc,
|
|
1
|
+
{"version":3,"file":"SentinelNotifier.d.ts","sourceRoot":"","sources":["../../src/monitoring/SentinelNotifier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,MAAM,MAAM,iBAAiB,GACzB,UAAU,GACV,QAAQ,GACR,WAAW,GACX,WAAW,GACX,iBAAiB,GACjB,uBAAuB,GACvB,aAAa,GACb,gBAAgB,GAChB,cAAc,GACd,YAAY,GAEZ,SAAS,GACT,aAAa,CAAC;AAElB,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,iBAAiB,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC;;;OAGG;IACH,GAAG,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACvC;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACtD,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,IAAI,EAAE,EAAE,EAAE,MAAM,KAAK,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;IACzE,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,KAAK,IAAI,CAAC;CAC9D;AAED,MAAM,WAAW,sBAAsB;IACrC;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAOD,qBAAa,gBAAgB;IAMzB,OAAO,CAAC,QAAQ,CAAC,IAAI;IALvB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAmC;IACvD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6B;IACrD,OAAO,CAAC,WAAW,CAA8C;gBAG9C,IAAI,EAAE,oBAAoB,EAC3C,GAAG,GAAE,sBAA2B;IAKlC,wDAAwD;IACxD,IAAI,eAAe,IAAI,OAAO,CAE7B;IAED;;;OAGG;IACH,MAAM,CAAC,IAAI,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;IAI7F;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAUnE,yDAAyD;IACnD,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAK/B,oDAAoD;IACpD,IAAI,IAAI,IAAI;IAKZ,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,UAAU;YAOJ,KAAK;IA2BnB,+EAA+E;IAC/E,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,KAAK;CAcd"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SentinelNotifier.js","sourceRoot":"","sources":["../../src/monitoring/SentinelNotifier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;
|
|
1
|
+
{"version":3,"file":"SentinelNotifier.js","sourceRoot":"","sources":["../../src/monitoring/SentinelNotifier.ts"],"names":[],"mappings":"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"}
|
|
@@ -127,6 +127,14 @@ export declare function buildActiveWorkSilenceDeps(opts: {
|
|
|
127
127
|
tracker: OutputActivityTracker;
|
|
128
128
|
sessions: SentinelSessionSurface;
|
|
129
129
|
escalate: EscalateFn;
|
|
130
|
+
/** Auto-recovery respawn primitive (DARK; only wired when autoRecover is on).
|
|
131
|
+
* Returns whether the respawn succeeded. */
|
|
132
|
+
recoverFn?: (sessionName: string) => Promise<boolean>;
|
|
133
|
+
/** Resolve a session to its Telegram topic, so silence/recovery notices land
|
|
134
|
+
* in the STALLED session's OWN topic (operator ask, 2026-06-09). */
|
|
135
|
+
getTopicForSession?: (sessionName: string) => number | null | undefined;
|
|
136
|
+
/** Deliver a notice to a specific topic. Returns success; never throws. */
|
|
137
|
+
deliverToTopic?: (topicId: number, text: string) => Promise<boolean>;
|
|
130
138
|
}): ActiveWorkSilenceSentinelDeps;
|
|
131
139
|
export type RecoveryReachKind = 'recovery-reached' | 'recovery-unreachable';
|
|
132
140
|
/** The neutral "continue" nudge — NOT a compaction-resume payload (which would
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sentinelWiring.d.ts","sourceRoot":"","sources":["../../src/monitoring/sentinelWiring.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"sentinelWiring.d.ts","sourceRoot":"","sources":["../../src/monitoring/sentinelWiring.ts"],"names":[],"mappings":"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"}
|