instar 1.3.243 → 1.3.245

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "instar",
3
- "version": "1.3.243",
3
+ "version": "1.3.245",
4
4
  "description": "Coherence infrastructure for self-evolving AI agents — on the Claude Code or Codex subscription you already have.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$schema": "./builtin-manifest.schema.json",
3
3
  "schemaVersion": 1,
4
- "generatedAt": "2026-06-04T07:16:51.612Z",
5
- "instarVersion": "1.3.243",
4
+ "generatedAt": "2026-06-04T18:14:33.049Z",
5
+ "instarVersion": "1.3.245",
6
6
  "entryCount": 198,
7
7
  "entries": {
8
8
  "hook:session-start": {
@@ -778,7 +778,7 @@
778
778
  "type": "cli-command",
779
779
  "domain": "setup",
780
780
  "sourcePath": "src/cli.ts",
781
- "contentHash": "410c6f2c325138a52996c3e2339d9b21fe7a32d90a20cc83d8754ad2d44e700f",
781
+ "contentHash": "cedd7aaca10839a47af5a19f09b3ce8509a978166a6e2c4994fcbaa4de0a459a",
782
782
  "since": "2025-01-01"
783
783
  },
784
784
  "cli:setup": {
@@ -786,7 +786,7 @@
786
786
  "type": "cli-command",
787
787
  "domain": "setup",
788
788
  "sourcePath": "src/cli.ts",
789
- "contentHash": "410c6f2c325138a52996c3e2339d9b21fe7a32d90a20cc83d8754ad2d44e700f",
789
+ "contentHash": "cedd7aaca10839a47af5a19f09b3ce8509a978166a6e2c4994fcbaa4de0a459a",
790
790
  "since": "2025-01-01"
791
791
  },
792
792
  "cli:add": {
@@ -794,7 +794,7 @@
794
794
  "type": "cli-command",
795
795
  "domain": "setup",
796
796
  "sourcePath": "src/cli.ts",
797
- "contentHash": "410c6f2c325138a52996c3e2339d9b21fe7a32d90a20cc83d8754ad2d44e700f",
797
+ "contentHash": "cedd7aaca10839a47af5a19f09b3ce8509a978166a6e2c4994fcbaa4de0a459a",
798
798
  "since": "2025-01-01"
799
799
  },
800
800
  "cli:backup": {
@@ -802,7 +802,7 @@
802
802
  "type": "cli-command",
803
803
  "domain": "operations",
804
804
  "sourcePath": "src/cli.ts",
805
- "contentHash": "410c6f2c325138a52996c3e2339d9b21fe7a32d90a20cc83d8754ad2d44e700f",
805
+ "contentHash": "cedd7aaca10839a47af5a19f09b3ce8509a978166a6e2c4994fcbaa4de0a459a",
806
806
  "since": "2025-01-01"
807
807
  },
808
808
  "cli:git": {
@@ -810,7 +810,7 @@
810
810
  "type": "cli-command",
811
811
  "domain": "coordination",
812
812
  "sourcePath": "src/cli.ts",
813
- "contentHash": "410c6f2c325138a52996c3e2339d9b21fe7a32d90a20cc83d8754ad2d44e700f",
813
+ "contentHash": "cedd7aaca10839a47af5a19f09b3ce8509a978166a6e2c4994fcbaa4de0a459a",
814
814
  "since": "2025-01-01"
815
815
  },
816
816
  "cli:memory": {
@@ -818,7 +818,7 @@
818
818
  "type": "cli-command",
819
819
  "domain": "memory",
820
820
  "sourcePath": "src/cli.ts",
821
- "contentHash": "410c6f2c325138a52996c3e2339d9b21fe7a32d90a20cc83d8754ad2d44e700f",
821
+ "contentHash": "cedd7aaca10839a47af5a19f09b3ce8509a978166a6e2c4994fcbaa4de0a459a",
822
822
  "since": "2025-01-01"
823
823
  },
824
824
  "cli:knowledge": {
@@ -826,7 +826,7 @@
826
826
  "type": "cli-command",
827
827
  "domain": "memory",
828
828
  "sourcePath": "src/cli.ts",
829
- "contentHash": "410c6f2c325138a52996c3e2339d9b21fe7a32d90a20cc83d8754ad2d44e700f",
829
+ "contentHash": "cedd7aaca10839a47af5a19f09b3ce8509a978166a6e2c4994fcbaa4de0a459a",
830
830
  "since": "2025-01-01"
831
831
  },
832
832
  "cli:semantic": {
@@ -834,7 +834,7 @@
834
834
  "type": "cli-command",
835
835
  "domain": "memory",
836
836
  "sourcePath": "src/cli.ts",
837
- "contentHash": "410c6f2c325138a52996c3e2339d9b21fe7a32d90a20cc83d8754ad2d44e700f",
837
+ "contentHash": "cedd7aaca10839a47af5a19f09b3ce8509a978166a6e2c4994fcbaa4de0a459a",
838
838
  "since": "2025-01-01"
839
839
  },
840
840
  "cli:intent": {
@@ -842,7 +842,7 @@
842
842
  "type": "cli-command",
843
843
  "domain": "intent",
844
844
  "sourcePath": "src/cli.ts",
845
- "contentHash": "410c6f2c325138a52996c3e2339d9b21fe7a32d90a20cc83d8754ad2d44e700f",
845
+ "contentHash": "cedd7aaca10839a47af5a19f09b3ce8509a978166a6e2c4994fcbaa4de0a459a",
846
846
  "since": "2025-01-01"
847
847
  },
848
848
  "cli:feedback": {
@@ -850,7 +850,7 @@
850
850
  "type": "cli-command",
851
851
  "domain": "feedback",
852
852
  "sourcePath": "src/cli.ts",
853
- "contentHash": "410c6f2c325138a52996c3e2339d9b21fe7a32d90a20cc83d8754ad2d44e700f",
853
+ "contentHash": "cedd7aaca10839a47af5a19f09b3ce8509a978166a6e2c4994fcbaa4de0a459a",
854
854
  "since": "2025-01-01"
855
855
  },
856
856
  "cli:server": {
@@ -858,7 +858,7 @@
858
858
  "type": "cli-command",
859
859
  "domain": "server",
860
860
  "sourcePath": "src/cli.ts",
861
- "contentHash": "410c6f2c325138a52996c3e2339d9b21fe7a32d90a20cc83d8754ad2d44e700f",
861
+ "contentHash": "cedd7aaca10839a47af5a19f09b3ce8509a978166a6e2c4994fcbaa4de0a459a",
862
862
  "since": "2025-01-01"
863
863
  },
864
864
  "cli:status": {
@@ -866,7 +866,7 @@
866
866
  "type": "cli-command",
867
867
  "domain": "monitoring",
868
868
  "sourcePath": "src/cli.ts",
869
- "contentHash": "410c6f2c325138a52996c3e2339d9b21fe7a32d90a20cc83d8754ad2d44e700f",
869
+ "contentHash": "cedd7aaca10839a47af5a19f09b3ce8509a978166a6e2c4994fcbaa4de0a459a",
870
870
  "since": "2025-01-01"
871
871
  },
872
872
  "cli:user": {
@@ -874,7 +874,7 @@
874
874
  "type": "cli-command",
875
875
  "domain": "users",
876
876
  "sourcePath": "src/cli.ts",
877
- "contentHash": "410c6f2c325138a52996c3e2339d9b21fe7a32d90a20cc83d8754ad2d44e700f",
877
+ "contentHash": "cedd7aaca10839a47af5a19f09b3ce8509a978166a6e2c4994fcbaa4de0a459a",
878
878
  "since": "2025-01-01"
879
879
  },
880
880
  "cli:relationship": {
@@ -882,7 +882,7 @@
882
882
  "type": "cli-command",
883
883
  "domain": "relationships",
884
884
  "sourcePath": "src/cli.ts",
885
- "contentHash": "410c6f2c325138a52996c3e2339d9b21fe7a32d90a20cc83d8754ad2d44e700f",
885
+ "contentHash": "cedd7aaca10839a47af5a19f09b3ce8509a978166a6e2c4994fcbaa4de0a459a",
886
886
  "since": "2025-01-01"
887
887
  },
888
888
  "cli:job": {
@@ -890,7 +890,7 @@
890
890
  "type": "cli-command",
891
891
  "domain": "scheduling",
892
892
  "sourcePath": "src/cli.ts",
893
- "contentHash": "410c6f2c325138a52996c3e2339d9b21fe7a32d90a20cc83d8754ad2d44e700f",
893
+ "contentHash": "cedd7aaca10839a47af5a19f09b3ce8509a978166a6e2c4994fcbaa4de0a459a",
894
894
  "since": "2025-01-01"
895
895
  },
896
896
  "cli:lifeline": {
@@ -898,7 +898,7 @@
898
898
  "type": "cli-command",
899
899
  "domain": "communication",
900
900
  "sourcePath": "src/cli.ts",
901
- "contentHash": "410c6f2c325138a52996c3e2339d9b21fe7a32d90a20cc83d8754ad2d44e700f",
901
+ "contentHash": "cedd7aaca10839a47af5a19f09b3ce8509a978166a6e2c4994fcbaa4de0a459a",
902
902
  "since": "2025-01-01"
903
903
  },
904
904
  "cli:list": {
@@ -906,7 +906,7 @@
906
906
  "type": "cli-command",
907
907
  "domain": "monitoring",
908
908
  "sourcePath": "src/cli.ts",
909
- "contentHash": "410c6f2c325138a52996c3e2339d9b21fe7a32d90a20cc83d8754ad2d44e700f",
909
+ "contentHash": "cedd7aaca10839a47af5a19f09b3ce8509a978166a6e2c4994fcbaa4de0a459a",
910
910
  "since": "2025-01-01"
911
911
  },
912
912
  "cli:autostart": {
@@ -914,7 +914,7 @@
914
914
  "type": "cli-command",
915
915
  "domain": "operations",
916
916
  "sourcePath": "src/cli.ts",
917
- "contentHash": "410c6f2c325138a52996c3e2339d9b21fe7a32d90a20cc83d8754ad2d44e700f",
917
+ "contentHash": "cedd7aaca10839a47af5a19f09b3ce8509a978166a6e2c4994fcbaa4de0a459a",
918
918
  "since": "2025-01-01"
919
919
  },
920
920
  "cli:migrate": {
@@ -922,7 +922,7 @@
922
922
  "type": "cli-command",
923
923
  "domain": "updates",
924
924
  "sourcePath": "src/cli.ts",
925
- "contentHash": "410c6f2c325138a52996c3e2339d9b21fe7a32d90a20cc83d8754ad2d44e700f",
925
+ "contentHash": "cedd7aaca10839a47af5a19f09b3ce8509a978166a6e2c4994fcbaa4de0a459a",
926
926
  "since": "2025-01-01"
927
927
  },
928
928
  "cli:machines": {
@@ -930,7 +930,7 @@
930
930
  "type": "cli-command",
931
931
  "domain": "coordination",
932
932
  "sourcePath": "src/cli.ts",
933
- "contentHash": "410c6f2c325138a52996c3e2339d9b21fe7a32d90a20cc83d8754ad2d44e700f",
933
+ "contentHash": "cedd7aaca10839a47af5a19f09b3ce8509a978166a6e2c4994fcbaa4de0a459a",
934
934
  "since": "2025-01-01"
935
935
  },
936
936
  "cli:whoami": {
@@ -938,7 +938,7 @@
938
938
  "type": "cli-command",
939
939
  "domain": "identity",
940
940
  "sourcePath": "src/cli.ts",
941
- "contentHash": "410c6f2c325138a52996c3e2339d9b21fe7a32d90a20cc83d8754ad2d44e700f",
941
+ "contentHash": "cedd7aaca10839a47af5a19f09b3ce8509a978166a6e2c4994fcbaa4de0a459a",
942
942
  "since": "2025-01-01"
943
943
  },
944
944
  "cli:pair": {
@@ -946,7 +946,7 @@
946
946
  "type": "cli-command",
947
947
  "domain": "coordination",
948
948
  "sourcePath": "src/cli.ts",
949
- "contentHash": "410c6f2c325138a52996c3e2339d9b21fe7a32d90a20cc83d8754ad2d44e700f",
949
+ "contentHash": "cedd7aaca10839a47af5a19f09b3ce8509a978166a6e2c4994fcbaa4de0a459a",
950
950
  "since": "2025-01-01"
951
951
  },
952
952
  "cli:join": {
@@ -954,7 +954,7 @@
954
954
  "type": "cli-command",
955
955
  "domain": "coordination",
956
956
  "sourcePath": "src/cli.ts",
957
- "contentHash": "410c6f2c325138a52996c3e2339d9b21fe7a32d90a20cc83d8754ad2d44e700f",
957
+ "contentHash": "cedd7aaca10839a47af5a19f09b3ce8509a978166a6e2c4994fcbaa4de0a459a",
958
958
  "since": "2025-01-01"
959
959
  },
960
960
  "cli:wakeup": {
@@ -962,7 +962,7 @@
962
962
  "type": "cli-command",
963
963
  "domain": "coordination",
964
964
  "sourcePath": "src/cli.ts",
965
- "contentHash": "410c6f2c325138a52996c3e2339d9b21fe7a32d90a20cc83d8754ad2d44e700f",
965
+ "contentHash": "cedd7aaca10839a47af5a19f09b3ce8509a978166a6e2c4994fcbaa4de0a459a",
966
966
  "since": "2025-01-01"
967
967
  },
968
968
  "cli:leave": {
@@ -970,7 +970,7 @@
970
970
  "type": "cli-command",
971
971
  "domain": "coordination",
972
972
  "sourcePath": "src/cli.ts",
973
- "contentHash": "410c6f2c325138a52996c3e2339d9b21fe7a32d90a20cc83d8754ad2d44e700f",
973
+ "contentHash": "cedd7aaca10839a47af5a19f09b3ce8509a978166a6e2c4994fcbaa4de0a459a",
974
974
  "since": "2025-01-01"
975
975
  },
976
976
  "cli:doctor": {
@@ -978,7 +978,7 @@
978
978
  "type": "cli-command",
979
979
  "domain": "monitoring",
980
980
  "sourcePath": "src/cli.ts",
981
- "contentHash": "410c6f2c325138a52996c3e2339d9b21fe7a32d90a20cc83d8754ad2d44e700f",
981
+ "contentHash": "cedd7aaca10839a47af5a19f09b3ce8509a978166a6e2c4994fcbaa4de0a459a",
982
982
  "since": "2025-01-01"
983
983
  },
984
984
  "cli:review": {
@@ -986,7 +986,7 @@
986
986
  "type": "cli-command",
987
987
  "domain": "monitoring",
988
988
  "sourcePath": "src/cli.ts",
989
- "contentHash": "410c6f2c325138a52996c3e2339d9b21fe7a32d90a20cc83d8754ad2d44e700f",
989
+ "contentHash": "cedd7aaca10839a47af5a19f09b3ce8509a978166a6e2c4994fcbaa4de0a459a",
990
990
  "since": "2025-01-01"
991
991
  },
992
992
  "cli:nuke": {
@@ -994,7 +994,7 @@
994
994
  "type": "cli-command",
995
995
  "domain": "operations",
996
996
  "sourcePath": "src/cli.ts",
997
- "contentHash": "410c6f2c325138a52996c3e2339d9b21fe7a32d90a20cc83d8754ad2d44e700f",
997
+ "contentHash": "cedd7aaca10839a47af5a19f09b3ce8509a978166a6e2c4994fcbaa4de0a459a",
998
998
  "since": "2025-01-01"
999
999
  },
1000
1000
  "cli:playbook": {
@@ -1002,7 +1002,7 @@
1002
1002
  "type": "cli-command",
1003
1003
  "domain": "context",
1004
1004
  "sourcePath": "src/cli.ts",
1005
- "contentHash": "410c6f2c325138a52996c3e2339d9b21fe7a32d90a20cc83d8754ad2d44e700f",
1005
+ "contentHash": "cedd7aaca10839a47af5a19f09b3ce8509a978166a6e2c4994fcbaa4de0a459a",
1006
1006
  "since": "2025-01-01"
1007
1007
  },
1008
1008
  "cli:dev-preflight": {
@@ -1010,7 +1010,7 @@
1010
1010
  "type": "cli-command",
1011
1011
  "domain": "development",
1012
1012
  "sourcePath": "src/cli.ts",
1013
- "contentHash": "410c6f2c325138a52996c3e2339d9b21fe7a32d90a20cc83d8754ad2d44e700f",
1013
+ "contentHash": "cedd7aaca10839a47af5a19f09b3ce8509a978166a6e2c4994fcbaa4de0a459a",
1014
1014
  "since": "2025-01-01"
1015
1015
  },
1016
1016
  "cli:dev-ci-failures": {
@@ -1018,7 +1018,7 @@
1018
1018
  "type": "cli-command",
1019
1019
  "domain": "development",
1020
1020
  "sourcePath": "src/cli.ts",
1021
- "contentHash": "410c6f2c325138a52996c3e2339d9b21fe7a32d90a20cc83d8754ad2d44e700f",
1021
+ "contentHash": "cedd7aaca10839a47af5a19f09b3ce8509a978166a6e2c4994fcbaa4de0a459a",
1022
1022
  "since": "2025-01-01"
1023
1023
  },
1024
1024
  "cli:dev-profile-node": {
@@ -1026,7 +1026,7 @@
1026
1026
  "type": "cli-command",
1027
1027
  "domain": "development",
1028
1028
  "sourcePath": "src/cli.ts",
1029
- "contentHash": "410c6f2c325138a52996c3e2339d9b21fe7a32d90a20cc83d8754ad2d44e700f",
1029
+ "contentHash": "cedd7aaca10839a47af5a19f09b3ce8509a978166a6e2c4994fcbaa4de0a459a",
1030
1030
  "since": "2025-01-01"
1031
1031
  },
1032
1032
  "template:build-stop-hook.sh": {
@@ -0,0 +1,23 @@
1
+ # Upgrade Guide — vNEXT
2
+
3
+ <!-- assembled-by: assemble-next-md -->
4
+ <!-- bump: patch -->
5
+
6
+ ## What Changed
7
+
8
+ - The Telegram authorized-user check is now type-tolerant. The legacy auth path compared the incoming numeric Telegram id against the configured `authorizedUserIds` with a strict membership check, so an id written as a string in config silently failed to match and the authorized user was treated as unknown (hitting the registration gate).
9
+ - The mini-onboarding auto-add now also compares ids loosely, so it no longer appends a duplicate when the configured list already holds the id as a string.
10
+
11
+ ## What to Tell Your User
12
+
13
+ - **Telegram access fix**: "If your Telegram user id was ever written as text in my config, I would have wrongly treated you as a stranger and asked you to register. That comparison now ignores whether the id is stored as a number or text, so the right person is recognized either way."
14
+
15
+ ## Summary of New Capabilities
16
+
17
+ | Capability | How to Use |
18
+ |-----------|-----------|
19
+ | Type-tolerant Telegram authorization | No action needed. Existing `authorizedUserIds` entries are honored whether they are stored as numbers or strings. |
20
+
21
+ ## Evidence
22
+
23
+ Added a focused unit test (`telegram-auth-id-type-tolerant.test.ts`, 5 cases) covering number-configured ids, string-configured ids (the regression), mixed lists, unauthorized rejection, and the empty/open passthrough. `tsc --noEmit` is clean. CI is the authority across the full shard matrix.
@@ -0,0 +1,39 @@
1
+ # Upgrade Guide — vNEXT
2
+
3
+ <!-- assembled-by: assemble-next-md -->
4
+ <!-- bump: patch -->
5
+
6
+ ## What Changed
7
+
8
+ Fixed the in-session server lifecycle guard so it only blocks the current
9
+ session's own managing server. Restarting a sibling agent server by target
10
+ directory or agent name is now allowed from inside a session.
11
+
12
+ Self-targeted server lifecycle commands are still blocked, and the error now
13
+ points operators to the supervisor path for bouncing that agent safely.
14
+
15
+ The CLI import shape remains compatible with the version-detection regression
16
+ test, and the exported guard is documented so docs coverage stays above the core
17
+ floor.
18
+
19
+ ## What to Tell Your User
20
+
21
+ - **Sibling agent restarts**: "I can now bounce another agent's server during
22
+ mentoring or fleet maintenance without being blocked by my own session guard.
23
+ My own managing server is still protected, so the active conversation is not
24
+ stranded by accident."
25
+
26
+ ## Summary of New Capabilities
27
+
28
+ | Capability | How to Use |
29
+ |-----------|-----------|
30
+ | Restart a sibling agent server from inside a session | Use the existing server lifecycle command with a sibling target |
31
+ | Safer self-server failure message | Automatic when an agent targets its own managing server |
32
+
33
+ ## Evidence
34
+
35
+ Reproduced the failing shape in a unit boundary test: a session with current
36
+ project Codey and target Gemini now returns allow, while current project Codey
37
+ targeting Codey still returns reject. The same targeted suite also verifies that
38
+ a symlink pointing back to Codey is rejected after realpath normalization. The
39
+ targeted server command test file passes with all ten tests green.
@@ -0,0 +1,96 @@
1
+ # Side-effects review — session-safe sibling server restarts
2
+
3
+ **Scope**: `instar server start|stop|restart` now checks whether the requested
4
+ server target is the current session's own project before blocking lifecycle
5
+ commands from inside a session. Sibling targets are allowed. Self-targets remain
6
+ blocked and now print an actionable supervisor command.
7
+
8
+ Framework-ledger ref: `57ecfb92`.
9
+
10
+ ## Decision audit
11
+
12
+ **Candidate A: keep the blanket block and only improve the error.**
13
+
14
+ This would have preserved the original safety invariant, but it would not remove
15
+ the operational friction that caused this task. A mentoring agent still could
16
+ not bounce a sibling agent's server from the correct workflow.
17
+
18
+ **Candidate B: make the guard target-aware and keep a supervisor hint for
19
+ self-targets.**
20
+
21
+ Chosen. It preserves the invariant that a session cannot restart its own
22
+ managing server, while allowing maintenance of sibling agents. The supervisor
23
+ hint covers the remaining blocked case with an explicit human/operator path.
24
+
25
+ ## Over-block risk
26
+
27
+ Low. The guard normalizes the current project and target project through
28
+ `realpath` when possible. Sibling directories compare different and are allowed.
29
+ The only expected block is the current managing server, including symlink aliases
30
+ that point back to it.
31
+
32
+ One residual over-block case remains intentional: if no target is provided from
33
+ inside a session, the command targets the current project and is blocked.
34
+
35
+ ## Under-block risk
36
+
37
+ Low. A symlink to the current project is rejected after realpath normalization.
38
+ If a target path does not exist yet, normalization falls back to `path.resolve`;
39
+ that could only affect non-existing paths before the server command validates
40
+ them. Existing self-targets are protected.
41
+
42
+ ## Level-of-abstraction fit
43
+
44
+ The comparison lives in a pure core helper. The CLI resolves the optional agent
45
+ name before asking the helper for a decision, then formats any rejection for the
46
+ terminal. This keeps policy separate from command output and makes the behavior
47
+ directly unit-testable.
48
+
49
+ ## Signal vs authority
50
+
51
+ The helper is authority for this CLI guard only. It does not change supervisor,
52
+ launchd, systemd, or server internals. The server lifecycle implementation still
53
+ owns the actual start/stop/restart mechanics.
54
+
55
+ ## Interactions
56
+
57
+ - `server start [name]`, `server stop [name]`, and `server restart [name]` now
58
+ resolve the agent name before applying the guard.
59
+ - `--dir` targets are compared directly.
60
+ - `status [name]` is unchanged except that `resolveAgentDir` is now statically
61
+ imported by the CLI.
62
+ - Supervisor-managed restarts remain the documented path for the current agent.
63
+
64
+ ## External surfaces
65
+
66
+ User-facing behavior changes only for CLI output and command allowance:
67
+
68
+ - Sibling server lifecycle commands from inside a session can proceed.
69
+ - Self server lifecycle commands still fail, with a clearer message and
70
+ `launchctl kickstart -k gui/$UID/ai.instar.<name>` hint.
71
+
72
+ No API keys, credentials, network calls, or config migrations are involved.
73
+
74
+ ## Rollback cost
75
+
76
+ Small. Reverting the helper, CLI call-site changes, tests, and upgrade artifacts
77
+ restores the prior blanket in-session block.
78
+
79
+ ## Tests
80
+
81
+ Narrow regression coverage checks:
82
+
83
+ - no session id allows lifecycle commands;
84
+ - current managing server rejects;
85
+ - sibling target allows;
86
+ - symlink target resolving to the current managing server rejects.
87
+ - docs coverage documents `SessionServerGuard` in two indexed docs so the core
88
+ category stays at its configured floor.
89
+
90
+ Local verification intentionally uses targeted tests and static gates under the
91
+ current host load; CI remains the full matrix authority.
92
+
93
+ ## Conclusion
94
+
95
+ This change removes the Gemini-onboarding friction without weakening the
96
+ conversation-safety invariant that motivated the guard in the first place.
@@ -0,0 +1,56 @@
1
+ # Side-Effects Review — Telegram authorizedUserIds type-tolerant comparison
2
+
3
+ **Version / slug:** `telegram-auth-id-type-tolerant`
4
+ **Date:** `2026-06-04`
5
+ **Author:** `echo`
6
+ **Second-pass reviewer:** `not required`
7
+
8
+ ## Summary of the change
9
+
10
+ The legacy (non-shared-AuthGate) Telegram auth path used
11
+ `authorizedUserIds.includes(userId)` where `userId` is a `number` but the config
12
+ field, though typed `number[]`, is untyped JSON at runtime and may hold the id as
13
+ a string. `Array.prototype.includes` uses SameValueZero (no coercion), so a
14
+ string-configured id silently failed to match and the authorized user was treated
15
+ as unknown. The fix compares as strings (`authorized.some(id => String(id) ===
16
+ String(userId))`), mirroring the shared-AuthGate path which is already string-based.
17
+ The mini-onboarding auto-add (`server.ts`) is given the same loose membership check
18
+ so it does not append a duplicate when the list already holds the id as a string.
19
+
20
+ ## Decision-point inventory
21
+
22
+ One decision point: `isAuthorized(userId)` returns true/false (authorized vs gated).
23
+ The change only affects WHICH equal-by-value ids match; it does not change the
24
+ empty-list semantics (still "accept all" on the legacy path) or any other branch.
25
+
26
+ ## 1. Over-block
27
+
28
+ **What legitimate inputs does this change reject?** None. The change only makes the
29
+ comparison match MORE inputs that were always intended to match (an id equal by
30
+ value, regardless of number-vs-string representation). No id that previously
31
+ authorized stops authorizing: `String(n) === String(n)` holds for every number that
32
+ `includes` would have matched. The empty/absent-list "accept all" path is untouched.
33
+
34
+ ## 2. Under-block
35
+
36
+ **What does this still miss?** It does not change the fail-open vs fail-closed
37
+ posture of the legacy path (empty list still accepts all — unchanged, out of scope).
38
+ It does not touch the shared-AuthGate path (already string-based) or the Slack/
39
+ WhatsApp/iMessage adapters (separate code, their own typing). It compares by exact
40
+ string equality after coercion, so it intentionally does NOT treat e.g. leading-zero
41
+ or whitespace-padded ids as equal — Telegram ids are canonical integers, so this is
42
+ correct.
43
+
44
+ ## 3. Blast radius
45
+
46
+ Two callsites: `TelegramAdapter.isAuthorized` (the auth gate) and the `server.ts`
47
+ mini-onboarding auto-add. Both are Telegram-only. No schema, config-shape, or API
48
+ change — existing configs (number ids, string ids, or mixed) all keep working, and
49
+ configs that already worked are unaffected. Behavior strictly widens recognition to
50
+ match the documented intent.
51
+
52
+ ## 4. Reversibility
53
+
54
+ Fully reversible: revert the two edits. No state migration, no persisted format
55
+ change. Config files are not rewritten by this change (the mini-onboarding still
56
+ pushes a numeric id as before; it just no longer duplicates an existing string id).