-
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathissues.json
More file actions
3609 lines (3525 loc) · 314 KB
/
Copy pathissues.json
File metadata and controls
3609 lines (3525 loc) · 314 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
[
{
"url": "https://api.github.com/repos/layer1labs/specsmith/issues/345",
"repository_url": "https://api.github.com/repos/layer1labs/specsmith",
"labels_url": "https://api.github.com/repos/layer1labs/specsmith/issues/345/labels{/name}",
"comments_url": "https://api.github.com/repos/layer1labs/specsmith/issues/345/comments",
"events_url": "https://api.github.com/repos/layer1labs/specsmith/issues/345/events",
"html_url": "https://github.com/layer1labs/specsmith/issues/345",
"id": 4905772837,
"node_id": "I_kwDOR2RC5c8AAAABJGgnJQ",
"number": 345,
"title": "Improve todo list rendering in agent output for readability",
"user": {
"login": "tbitcs",
"id": 98970594,
"node_id": "U_kgDOBeYr4g",
"avatar_url": "https://avatars.githubusercontent.com/u/98970594?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/tbitcs",
"html_url": "https://github.com/tbitcs",
"followers_url": "https://api.github.com/users/tbitcs/followers",
"following_url": "https://api.github.com/users/tbitcs/following{/other_user}",
"gists_url": "https://api.github.com/users/tbitcs/gists{/gist_id}",
"starred_url": "https://api.github.com/users/tbitcs/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/tbitcs/subscriptions",
"organizations_url": "https://api.github.com/users/tbitcs/orgs",
"repos_url": "https://api.github.com/users/tbitcs/repos",
"events_url": "https://api.github.com/users/tbitcs/events{/privacy}",
"received_events_url": "https://api.github.com/users/tbitcs/received_events",
"type": "User",
"user_view_type": "public",
"site_admin": false
},
"labels": [
],
"state": "open",
"locked": false,
"assignees": [
],
"milestone": null,
"comments": 0,
"created_at": "2026-07-16T20:32:13Z",
"updated_at": "2026-07-16T20:32:13Z",
"closed_at": null,
"assignee": null,
"author_association": "CONTRIBUTOR",
"issue_field_values": [
],
"type": null,
"active_lock_reason": null,
"sub_issues_summary": {
"total": 0,
"completed": 0,
"percent_completed": 0
},
"issue_dependencies_summary": {
"blocked_by": 0,
"total_blocked_by": 0,
"blocking": 0,
"total_blocking": 0
},
"body": "## UX: Todo list output formatting improvement\\n\\nThe current todo list rendering in agent output is hard to read. It uses plain text with inline markdown checkboxes that get compressed and are difficult to scan.\\n\\n### Current Format (Problem)\\n\\n```\\nUpdated the to-do list\\nFix unconditional response.json() calls in App.tsx (root cause of JSON parse errors)\\\\n- [x] Create comprehensive Playwright E2E test suite for data correctness, UI elements, styling\\\\n- [-] Fix studio-data-and-ui.spec.ts syntax errors and service ID issues\\\\n - [x] Add missing `});` to close `navigateAndWait` function\\\\n - [x] Add missing `});` to close first test\\\\n - [x] Change `service-studio` → `service-api` (studio at index 0 is sliced out)\\\\n - [x] Fix `navigateAndWait` to pass hash URLs directly (was stripping `#`)\\\\n - [ ] Rebuild and re-run tests\\\\n - [ ] Fix remaining failures\\\\n- [ ] Verify against Specsmith governance\\n```\\n\\nIssues:\\n- Sub-items use inconsistent indentation (space vs tab)\\n- Long parent items run into child items\\n- No visual separation between top-level and nested items\\n- Status indicators (`[x]`, `[-]`, `[ ]`) are not visually distinct\\n- Paused state info is appended without clear formatting\\n\\n### Proposed Format (Solution)\\n\\n```\\n## Updated the to-do list\\n\\n### Fix unconditional response.json() calls in App.tsx\\n- [x] Create comprehensive Playwright E2E test suite\\n- [x] Add missing `});` to close `navigateAndWait` function\\n- [x] Add missing `});` to close first test\\n- [x] Change `service-studio` → `service-api`\\n- [x] Fix `navigateAndWait` to pass hash URLs directly\\n- [ ] Rebuild and re-run tests\\n- [ ] Fix remaining failures\\n\\n### Verify against Specsmith governance\\n- [ ] Run governance checkpoint\\n```\\n\\n### Acceptance Criteria\\n\\n- [ ] Each top-level todo item gets its own `###` heading or clear separator\\n- [ ] Sub-items use consistent 2-space indentation under parent\\n- [ ] Status badges or emoji indicators for visual distinction:\\n - `[x]` → ✅ completed\\n - `[-]` → 🔄 in progress\\n - `[ ]` → ⏳ pending\\n- [ ] Paused/resumed state shown in a collapsible or clearly separated block\\n- [ ] Long item titles are truncated with ellipsis when exceeding 60 chars\\n- [ ] Format is consistent across all agent modes (code, architect, debug, etc.)\\n\\n### Implementation Notes\\n\\n- Modify the `update_todo_list` tool output formatting in agent response generation\\n- Consider a dedicated rendering function for todo lists in agent output\\n- Ensure markdown compatibility across all output surfaces (terminal, IDE, web UI)\\n- Test with deeply nested todo lists (3+ levels)\\n\\n### Labels\\n\\n`ux`, `enhancement`, `agent-output`, `readability`",
"closed_by": null,
"reactions": {
"url": "https://api.github.com/repos/layer1labs/specsmith/issues/345/reactions",
"total_count": 0,
"+1": 0,
"-1": 0,
"laugh": 0,
"hooray": 0,
"confused": 0,
"heart": 0,
"rocket": 0,
"eyes": 0
},
"timeline_url": "https://api.github.com/repos/layer1labs/specsmith/issues/345/timeline",
"performed_via_github_app": null,
"state_reason": null,
"pinned_comment": null
},
{
"url": "https://api.github.com/repos/layer1labs/specsmith/issues/344",
"repository_url": "https://api.github.com/repos/layer1labs/specsmith",
"labels_url": "https://api.github.com/repos/layer1labs/specsmith/issues/344/labels{/name}",
"comments_url": "https://api.github.com/repos/layer1labs/specsmith/issues/344/comments",
"events_url": "https://api.github.com/repos/layer1labs/specsmith/issues/344/events",
"html_url": "https://github.com/layer1labs/specsmith/issues/344",
"id": 4905311566,
"node_id": "I_kwDOR2RC5c8AAAABJGEdTg",
"number": 344,
"title": "Model generates malformed diff format: :start_line: marker in REPLACE section causes edit failures",
"user": {
"login": "tbitcs",
"id": 98970594,
"node_id": "U_kgDOBeYr4g",
"avatar_url": "https://avatars.githubusercontent.com/u/98970594?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/tbitcs",
"html_url": "https://github.com/tbitcs",
"followers_url": "https://api.github.com/users/tbitcs/followers",
"following_url": "https://api.github.com/users/tbitcs/following{/other_user}",
"gists_url": "https://api.github.com/users/tbitcs/gists{/gist_id}",
"starred_url": "https://api.github.com/users/tbitcs/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/tbitcs/subscriptions",
"organizations_url": "https://api.github.com/users/tbitcs/orgs",
"repos_url": "https://api.github.com/users/tbitcs/repos",
"events_url": "https://api.github.com/users/tbitcs/events{/privacy}",
"received_events_url": "https://api.github.com/users/tbitcs/received_events",
"type": "User",
"user_view_type": "public",
"site_admin": false
},
"labels": [
],
"state": "open",
"locked": false,
"assignees": [
],
"milestone": null,
"comments": 0,
"created_at": "2026-07-16T19:26:11Z",
"updated_at": "2026-07-16T19:26:11Z",
"closed_at": null,
"assignee": null,
"author_association": "CONTRIBUTOR",
"issue_field_values": [
],
"type": null,
"active_lock_reason": null,
"sub_issues_summary": {
"total": 0,
"completed": 0,
"percent_completed": 0
},
"issue_dependencies_summary": {
"blocked_by": 0,
"total_blocked_by": 0,
"blocking": 0,
"total_blocking": 0
},
"body": "## Bug: Malformed diff format from model tool use\\n\\nZoo Code (and potentially other AI agents) is generating diffs with `:start_line:` markers in the **REPLACE** section instead of the **SEARCH** section, causing `apply_diff` failures.\\n\\n### Error Details\\n\\n```\\nERROR: Invalid line marker ':start_line:' found in REPLACE section at line 4\\n\\nLine markers (:start_line: and :end_line:) are only allowed in SEARCH sections.\\n\\nCORRECT FORMAT:\\n<<<<<<< SEARCH\\n:start_line:5\\ncontent to find\\n=======\\nreplacement content\\n>>>>>>> REPLACE\\n\\nINCORRECT FORMAT:\\n<<<<<<< SEARCH\\ncontent to find\\n=======\\n:start_line:5 <-- Invalid location\\nreplacement content\\n>>>>>>> REPLACE\\n```\\n\\n### Affected File\\n\\n- `c:\\\\Users\\\\trist\\\\Development\\\\Layer1Labs\\\\chronofabric\\\\chronofabric-ip\\\\scripts\\\\bootstrap.py`\\n- Truncation at line 538 inside `platform_map` dict\\n\\n### Environment\\n\\n- Date/time: 2026-07-16T19:22:19.431Z\\n- Extension version: 3.68.0\\n- Provider: litellm (proxy)\\n- Model: ChronoCortex-LLM\\n\\n### Root Cause Analysis Needed\\n\\n1. **Model training gap**: The model does not correctly associate `:start_line:` with the SEARCH block\\n2. **Tool-use instruction clarity**: The diff format spec may need reinforcement in system prompts\\n3. **Truncation handling**: When files are truncated, the model may lose context about where markers belong\\n\\n### Reproduction Steps\\n\\n1. Open a file with a large dict (e.g., `platform_map` with 500+ lines)\\n2. Ask the model to replace a truncated/incomplete section\\n3. Model generates diff with `:start_line:` in REPLACE block\\n4. `apply_diff` tool rejects the edit\\n\\n### Acceptance Criteria\\n\\n- [ ] System prompt or tool instructions explicitly reinforce `:start_line:` placement in SEARCH blocks only\\n- [ ] Model generates valid diff format for truncated file edits\\n- [ ] Fallback strategy documented (e.g., `write_to_file` when diffs fail repeatedly)\\n- [ ] Error recovery flow: on `apply_diff` failure, retry with corrected format or switch to full file write\\n\\n### Mitigation for Users (Workaround)\\n\\nUntil fixed, users can:\\n- Break large edits into smaller, targeted changes\\n- Use `write_to_file` for complete file rewrites instead of `apply_diff` for truncated sections\\n- Manually specify the exact content to search for without line markers\\n\\n### Labels\\n\\n`bug`, `tool-use`, `model-training`, `diff-format`, `zoo-code`",
"closed_by": null,
"reactions": {
"url": "https://api.github.com/repos/layer1labs/specsmith/issues/344/reactions",
"total_count": 0,
"+1": 0,
"-1": 0,
"laugh": 0,
"hooray": 0,
"confused": 0,
"heart": 0,
"rocket": 0,
"eyes": 0
},
"timeline_url": "https://api.github.com/repos/layer1labs/specsmith/issues/344/timeline",
"performed_via_github_app": null,
"state_reason": null,
"pinned_comment": null
},
{
"url": "https://api.github.com/repos/layer1labs/specsmith/issues/343",
"repository_url": "https://api.github.com/repos/layer1labs/specsmith",
"labels_url": "https://api.github.com/repos/layer1labs/specsmith/issues/343/labels{/name}",
"comments_url": "https://api.github.com/repos/layer1labs/specsmith/issues/343/comments",
"events_url": "https://api.github.com/repos/layer1labs/specsmith/issues/343/events",
"html_url": "https://github.com/layer1labs/specsmith/issues/343",
"id": 4905299491,
"node_id": "I_kwDOR2RC5c8AAAABJGDuIw",
"number": 343,
"title": "Define optimal invocation strategy: MCP vs /slash commands vs skills vs direct CLI",
"user": {
"login": "tbitcs",
"id": 98970594,
"node_id": "U_kgDOBeYr4g",
"avatar_url": "https://avatars.githubusercontent.com/u/98970594?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/tbitcs",
"html_url": "https://github.com/tbitcs",
"followers_url": "https://api.github.com/users/tbitcs/followers",
"following_url": "https://api.github.com/users/tbitcs/following{/other_user}",
"gists_url": "https://api.github.com/users/tbitcs/gists{/gist_id}",
"starred_url": "https://api.github.com/users/tbitcs/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/tbitcs/subscriptions",
"organizations_url": "https://api.github.com/users/tbitcs/orgs",
"repos_url": "https://api.github.com/users/tbitcs/repos",
"events_url": "https://api.github.com/users/tbitcs/events{/privacy}",
"received_events_url": "https://api.github.com/users/tbitcs/received_events",
"type": "User",
"user_view_type": "public",
"site_admin": false
},
"labels": [
],
"state": "open",
"locked": false,
"assignees": [
],
"milestone": null,
"comments": 0,
"created_at": "2026-07-16T19:24:33Z",
"updated_at": "2026-07-16T19:24:33Z",
"closed_at": null,
"assignee": null,
"author_association": "CONTRIBUTOR",
"issue_field_values": [
],
"type": null,
"active_lock_reason": null,
"sub_issues_summary": {
"total": 0,
"completed": 0,
"percent_completed": 0
},
"issue_dependencies_summary": {
"blocked_by": 0,
"total_blocked_by": 0,
"blocking": 0,
"total_blocking": 0
},
"body": "## Epic: Invocation Strategy Optimization\\n\\nSpecsmith supports multiple invocation mechanisms. This ticket defines when each should be used for optimal UX, reliability, and cross-environment compatibility.\\n\\n### Invocation Mechanisms\\n\\n1. **MCP (Model Context Protocol)** — `governance_preflight`, `governance_audit`, `governance_checkpoint`, etc.\\n - Best for: AI agent-to-agent communication, structured governance decisions, programmatic access\\n - Environments: Cursor, VS Code extensions, any MCP-compatible client\\n - Pros: Structured JSON I/O, governance-enforced, traceable\\n - Cons: Requires MCP server running, limited to MCP-defined tools\\n\\n2. **Slash Commands** — `/specsmith save`, `/specsmith audit`, `/specsmith status`, etc. (REPL)\\n - Best for: Interactive sessions, quick governance operations, human operators\\n - Environments: Nexus REPL, any terminal with REPL mode\\n - Pros: Simple syntax, built into specsmith CLI, no extra setup\\n - Cons: REPL-bound, not scriptable in non-interactive contexts\\n\\n3. **Skills** — Loaded via `skill` tool (e.g., `execution`, `git`, `release`, `testing-*`)\\n - Best for: Complex, multi-step workflows with specific domain procedures\\n - Environments: AI agents with skill-loading capability\\n - Pros: Rich procedural instructions, domain-specific guidance\\n - Cons: Skill must be loaded first, adds context overhead\\n\\n4. **Direct CLI** — `specsmith preflight`, `specsmith audit`, `specsmith sync`, `specsmith checkpoint`, etc.\\n - Best for: Scripting, CI/CD pipelines, automation, shell scripts\\n - Environments: Any shell (bash, pwsh, cmd), CI runners\\n - Pros: Fully scriptable, no server required, works in headless environments\\n - Cons: Less structured output, no built-in governance enforcement without flags\\n\\n### Decision Matrix\\n\\n| Scenario | Preferred | Fallback |\\n|---|---|---|\\n| AI agent in IDE (Cursor/VS Code) | MCP tools | Slash commands |\\n| Interactive terminal session | Slash commands | Direct CLI |\\n| Complex domain workflow | Skill | Direct CLI |\\n| CI/CD pipeline | Direct CLI | MCP (if server available) |\\n| Headless/server environments | Direct CLI | — |\\n| Cross-platform automation | Direct CLI | — |\\n| Governance-enforced decisions | MCP tools | Direct CLI with `--json` |\\n\\n### Integration Considerations\\n\\n- **Zoo Code**: Prefers MCP for governance decisions, slash commands for quick ops\\n- **Local LLM agents**: Direct CLI (no MCP server needed)\\n- **Remote CI runners**: Direct CLI with `SPECSMITH_ALLOW_NON_PIPX=1` as needed\\n- **Multi-agent coordination**: MCP for structured handoffs\\n\\n### Acceptance Criteria\\n\\n- [ ] Decision matrix documented in AGENTS.md or docs/\\n- [ ] Clear guidance on when each mechanism is appropriate\\n- [ ] Fallback strategies documented\\n- [ ] Environment compatibility matrix (Windows/Linux/macOS, IDE/headless)\\n- [ ] Zoo Code integration notes included\\n\\n### Labels\\n\\n`epic`, `documentation`, `ux`, `cross-platform`",
"closed_by": null,
"reactions": {
"url": "https://api.github.com/repos/layer1labs/specsmith/issues/343/reactions",
"total_count": 0,
"+1": 0,
"-1": 0,
"laugh": 0,
"hooray": 0,
"confused": 0,
"heart": 0,
"rocket": 0,
"eyes": 0
},
"timeline_url": "https://api.github.com/repos/layer1labs/specsmith/issues/343/timeline",
"performed_via_github_app": null,
"state_reason": null,
"pinned_comment": null
},
{
"url": "https://api.github.com/repos/layer1labs/specsmith/issues/342",
"repository_url": "https://api.github.com/repos/layer1labs/specsmith",
"labels_url": "https://api.github.com/repos/layer1labs/specsmith/issues/342/labels{/name}",
"comments_url": "https://api.github.com/repos/layer1labs/specsmith/issues/342/comments",
"events_url": "https://api.github.com/repos/layer1labs/specsmith/issues/342/events",
"html_url": "https://github.com/layer1labs/specsmith/issues/342",
"id": 4905261241,
"node_id": "I_kwDOR2RC5c8AAAABJGBYuQ",
"number": 342,
"title": "Windows pipx CLI startup can hang in Click/gettext before command dispatch",
"user": {
"login": "tbitcs",
"id": 98970594,
"node_id": "U_kgDOBeYr4g",
"avatar_url": "https://avatars.githubusercontent.com/u/98970594?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/tbitcs",
"html_url": "https://github.com/tbitcs",
"followers_url": "https://api.github.com/users/tbitcs/followers",
"following_url": "https://api.github.com/users/tbitcs/following{/other_user}",
"gists_url": "https://api.github.com/users/tbitcs/gists{/gist_id}",
"starred_url": "https://api.github.com/users/tbitcs/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/tbitcs/subscriptions",
"organizations_url": "https://api.github.com/users/tbitcs/orgs",
"repos_url": "https://api.github.com/users/tbitcs/repos",
"events_url": "https://api.github.com/users/tbitcs/events{/privacy}",
"received_events_url": "https://api.github.com/users/tbitcs/received_events",
"type": "User",
"user_view_type": "public",
"site_admin": false
},
"labels": [
],
"state": "open",
"locked": false,
"assignees": [
],
"milestone": null,
"comments": 0,
"created_at": "2026-07-16T19:19:26Z",
"updated_at": "2026-07-16T19:20:07Z",
"closed_at": null,
"assignee": null,
"author_association": "CONTRIBUTOR",
"issue_field_values": [
],
"type": null,
"active_lock_reason": null,
"sub_issues_summary": {
"total": 0,
"completed": 0,
"percent_completed": 0
},
"issue_dependencies_summary": {
"blocked_by": 0,
"total_blocked_by": 0,
"blocking": 0,
"total_blocking": 0
},
"body": "## Objective\n\nPrevent `specsmith` from hanging or taking unbounded time during CLI import and command registration on Windows before the requested subcommand is dispatched.\n\nThis was observed with a pipx-installed Specsmith using Python 3.12 on Windows PowerShell. It is not currently covered by another open issue. It is related to the cross-platform audit in #330, but is a distinct public-CLI startup defect. It follows the test-evidence contract in #337.\n\n## Observed reproduction\n\nWorking directory:\n\n```text\nC:\\Users\\trist\\Development\\Creative Racing\\crscale\n```\n\nCommand:\n\n```powershell\nspecsmith load\n```\n\nObserved stack at manual interruption:\n\n```text\nFile \"...\\specsmith\\cli.py\", line 13894, in <module>\n from specsmith.commands.reporting import register_reporting_commands\nFile \"...\\specsmith\\commands\\reporting.py\", line 494, in <module>\n @click.option(\"--project-dir\", type=click.Path(exists=True), default=\".\")\nFile \"...\\click\\types.py\", line 1073, in __init__\n self.name = _(\"path\")\nFile \"...\\gettext.py\", line 617, in gettext\n return dgettext(_current_domain, message)\nFile \"...\\gettext.py\", line 523, in translation\n mofiles = find(domain, localedir, languages, all=True)\nFile \"...\\gettext.py\", line 507, in find\n if os.path.exists(mofile):\nKeyboardInterrupt\n```\n\nEnvironment visible in the traceback:\n\n- Windows PowerShell\n- pipx executable: `C:\\Users\\trist\\.local\\bin\\specsmith.exe`\n- pipx environment: `C:\\Users\\trist\\AppData\\Local\\pipx\\pipx\\venvs\\specsmith`\n- Python 3.12 runtime under `AppData\\Local\\Python\\pythoncore-3.12-64`\n- repository path contains spaces\n\nThe final `KeyboardInterrupt` means the user manually stopped a startup hang; it is not the underlying error.\n\n## Current-state evidence\n\nOn current `main`:\n\n- `specsmith.cli` eagerly imports `specsmith.commands.reporting` during module initialization;\n- `reporting.py` constructs Click decorators such as `click.Path(exists=True)` at import time;\n- Click initializes translated type names through Python `gettext` while those decorators are created;\n- command registration occurs before Click can dispatch `load`;\n- therefore a slow or pathological locale lookup in an unrelated command module can block every CLI command.\n\nThe import is wrapped in `except Exception`, but `KeyboardInterrupt` derives from `BaseException`, not `Exception`, and the import has already blocked before normal command handling can proceed. Broadly swallowing import exceptions is also not an acceptable fix because it can silently remove commands.\n\n## Required investigation\n\nReproduce and profile startup using the same installation topology:\n\n1. Windows hosted runner or Windows VM;\n2. Python 3.12 and at least one other supported Python version;\n3. pipx installation, not only an editable virtual environment;\n4. PowerShell invocation;\n5. working directory containing spaces;\n6. representative `LANG`, `LC_ALL`, `LANGUAGE`, and Windows locale combinations;\n7. cold and warm filesystem/cache states.\n\nCapture timing and stack evidence for:\n\n- Python import time;\n- Click command-tree construction;\n- gettext domain/language resolution;\n- filesystem probes generated by gettext;\n- endpoint-security or unavailable-drive interactions where reproducible;\n- difference between importing `specsmith.cli`, importing `reporting.py`, and constructing one `click.Path` instance.\n\nDo not assume `click.Path` itself is defective until isolated. The stack shows where the thread was interrupted, not necessarily the sole root cause.\n\n## Required behavior\n\n- Every basic CLI command must dispatch within a bounded startup time under supported Windows/pipx configurations.\n- `specsmith load` must not import or construct unrelated heavyweight command modules before dispatch unless required by the chosen CLI architecture.\n- Command registration failures must be visible and actionable; commands must not disappear silently behind broad `except Exception: pass` blocks.\n- Locale initialization must be deterministic and must not trigger unbounded filesystem searches.\n- Startup behavior must remain compatible with supported localization behavior in Click.\n- The fix must not special-case the user's path or disable localization globally without evidence and documentation.\n- The implementation should prefer modular/lazy command loading or another bounded registration strategy if eager construction is the amplifying design flaw.\n- Add a startup diagnostic mode or documented profiling command that identifies slow command-module imports without requiring the CLI to finish normal dispatch.\n\n## Suggested implementation directions to evaluate\n\nThese are investigation candidates, not predetermined solutions:\n\n1. Lazy-load command groups/modules only when their command namespace is selected.\n2. Move decorator/type construction out of global import paths where practical.\n3. Replace the broad reporting import suppression with explicit registration and actionable failure reporting.\n4. Cache or constrain locale resolution only if profiling proves gettext lookup is the root cause.\n5. Pin or constrain Click only if an upstream regression is demonstrated and linked.\n6. Ensure packaged locale/environment metadata does not point gettext at invalid, network, or excessively broad paths.\n\n## Named tests and binary pass/fail conditions\n\n### CLI-START-001 — Windows pipx load startup\n\n**Fixture:** install the built wheel with pipx on Windows using Python 3.12; invoke `specsmith load` from a project path containing spaces.\n\n**Pass:** the process reaches command execution or a normal project-level response within the configured startup budget and never requires manual interruption.\n\n**Fail:** startup times out, remains in import/Click/gettext initialization, or produces no bounded diagnostic.\n\n### CLI-START-002 — Basic command startup matrix\n\n**Fixture:** invoke `--help`, `--version`, `load`, `save`, `doctor`, and one reporting command from a pipx install.\n\n**Pass:** every command dispatches within the startup budget; unrelated command modules cannot block `--version`, `--help`, or `load`.\n\n**Fail:** any command hangs during command-tree construction or imports unrelated optional functionality before dispatch.\n\n### CLI-START-003 — Locale matrix\n\n**Fixture:** supported Windows locale plus explicit unset, valid, invalid, and multi-entry values for `LANG`, `LC_ALL`, and `LANGUAGE`.\n\n**Pass:** startup is bounded and diagnostics identify unsupported locale values without hanging.\n\n**Fail:** any locale combination causes unbounded gettext path probing or silent command loss.\n\n### CLI-START-004 — Cold-start filesystem behavior\n\n**Fixture:** cold process with empty Python/Click caches and instrumentation of filesystem probes.\n\n**Pass:** locale and command registration perform a bounded number of local probes and do not enumerate unavailable/network roots.\n\n**Fail:** startup performs unbounded/repeated existence checks or depends on an unavailable drive/share.\n\n### CLI-START-005 — Reporting isolation\n\n**Fixture:** instrument imports while invoking `specsmith load`.\n\n**Pass:** either `reporting.py` is not imported before `load` dispatch, or its registration is proven bounded below the startup budget.\n\n**Fail:** an unrelated reporting command can block `load` indefinitely.\n\n### CLI-START-006 — Registration failure visibility\n\n**Fixture:** inject a deterministic import/registration error into an optional command module.\n\n**Pass:** the CLI reports the failed module and remediation while preserving commands that can safely operate; no bare `pass` hides the defect.\n\n**Fail:** the command silently disappears or all commands crash without identifying the registration failure.\n\n### CLI-START-007 — KeyboardInterrupt handling\n\n**Fixture:** interrupt during intentionally delayed command registration.\n\n**Pass:** the process exits promptly with a clear interruption status and no corrupted state.\n\n**Fail:** interruption is swallowed, misreported as a normal command error, or leaves persistent state half-written.\n\n### CLI-START-008 — Supported Python matrix\n\n**Fixture:** Windows pipx installs across supported Python versions, including 3.12.\n\n**Pass:** startup semantics and budgets are equivalent across the supported matrix.\n\n**Fail:** the defect is hidden by testing only editable installs or one Python version.\n\n### CLI-START-009 — Import-time performance budget\n\n**Fixture:** automated timing for `python -c \"import specsmith.cli\"` and real console-script dispatch.\n\n**Pass:** both remain under an explicitly documented CI budget with a reasonable hosted-runner tolerance; regressions fail CI with per-module timing evidence.\n\n**Fail:** no enforceable budget exists or timing failures provide no localization data.\n\n### CLI-START-010 — Packaged-wheel parity\n\n**Fixture:** compare source checkout, ordinary venv wheel install, and pipx wheel install.\n\n**Pass:** all use the same registered command surface and none hang; differences are recorded and justified.\n\n**Fail:** tests pass only in the source checkout while the published installation topology remains broken.\n\n### CLI-START-011 — Path-character coverage\n\n**Fixture:** working directories containing spaces, Unicode, parentheses, and long Windows paths within supported limits.\n\n**Pass:** CLI startup and command dispatch remain bounded and path-correct.\n\n**Fail:** path spelling changes locale lookup behavior or prevents dispatch.\n\n### CLI-START-012 — No silent command loss\n\n**Fixture:** enumerate the expected public command surface after startup.\n\n**Pass:** every expected command is present, or an unavailable optional command has an explicit recorded reason.\n\n**Fail:** broad exception handling silently removes a command group.\n\n## Acceptance criteria\n\n- [ ] The reported Windows/pipx reproduction no longer hangs.\n- [ ] Root cause is demonstrated with timing/stack evidence rather than inferred solely from the interrupted frame.\n- [ ] CLI dispatch has an explicit, automated startup budget.\n- [ ] Unrelated command modules cannot indefinitely block `load`, `--help`, or `--version`.\n- [ ] Command registration errors are not silently swallowed.\n- [ ] Published-wheel and pipx topology are tested on Windows.\n- [ ] CLI-START-001 through CLI-START-012 pass with machine-readable evidence under #337.\n\n## Relationship to other tickets\n\n- #330: include this regression in the broader cross-platform release/bootstrap audit, but do not close this ticket based only on release CI portability.\n- #313: shell selection happens after CLI startup and does not resolve this import-time hang.\n- #341: Zoo settings lifecycle is unrelated except that its CLI entry points also require bounded startup.\n\n## Non-goals\n\n- Do not treat activation of the repository's `tests\\.venv` after the failure as the fix; the failing `specsmith.exe` came from the pipx environment.\n- Do not close the issue merely because retrying after caches warm happens to succeed.\n- Do not remove reporting commands to make startup faster.\n- Do not disable all localization without a verified compatibility decision.",
"closed_by": null,
"reactions": {
"url": "https://api.github.com/repos/layer1labs/specsmith/issues/342/reactions",
"total_count": 0,
"+1": 0,
"-1": 0,
"laugh": 0,
"hooray": 0,
"confused": 0,
"heart": 0,
"rocket": 0,
"eyes": 0
},
"timeline_url": "https://api.github.com/repos/layer1labs/specsmith/issues/342/timeline",
"performed_via_github_app": {
"id": 1144995,
"client_id": "Iv23liVemv8A9if9v0F2",
"slug": "chatgpt-codex-connector",
"node_id": "A_kwHOAOQ6Gs4AEXij",
"owner": {
"login": "openai",
"id": 14957082,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjE0OTU3MDgy",
"avatar_url": "https://avatars.githubusercontent.com/u/14957082?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/openai",
"html_url": "https://github.com/openai",
"followers_url": "https://api.github.com/users/openai/followers",
"following_url": "https://api.github.com/users/openai/following{/other_user}",
"gists_url": "https://api.github.com/users/openai/gists{/gist_id}",
"starred_url": "https://api.github.com/users/openai/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/openai/subscriptions",
"organizations_url": "https://api.github.com/users/openai/orgs",
"repos_url": "https://api.github.com/users/openai/repos",
"events_url": "https://api.github.com/users/openai/events{/privacy}",
"received_events_url": "https://api.github.com/users/openai/received_events",
"type": "Organization",
"user_view_type": "public",
"site_admin": false
},
"name": "ChatGPT Codex Connector",
"description": "Bring ChatGPT and Codex to your GitHub repositories.",
"external_url": "https://www.chatgpt.com",
"html_url": "https://github.com/apps/chatgpt-codex-connector",
"created_at": "2025-02-14T01:37:05Z",
"updated_at": "2026-04-20T16:37:15Z",
"permissions": {
"actions": "write",
"checks": "read",
"contents": "write",
"emails": "read",
"issues": "write",
"metadata": "read",
"pull_requests": "write",
"statuses": "read",
"workflows": "write"
},
"events": [
"check_run",
"check_suite",
"commit_comment",
"issues",
"issue_comment",
"pull_request",
"pull_request_review",
"pull_request_review_comment",
"pull_request_review_thread",
"repository",
"status",
"sub_issues"
]
},
"state_reason": null,
"pinned_comment": null
},
{
"url": "https://api.github.com/repos/layer1labs/specsmith/issues/341",
"repository_url": "https://api.github.com/repos/layer1labs/specsmith",
"labels_url": "https://api.github.com/repos/layer1labs/specsmith/issues/341/labels{/name}",
"comments_url": "https://api.github.com/repos/layer1labs/specsmith/issues/341/comments",
"events_url": "https://api.github.com/repos/layer1labs/specsmith/issues/341/events",
"html_url": "https://github.com/layer1labs/specsmith/issues/341",
"id": 4905038235,
"node_id": "I_kwDOR2RC5c8AAAABJFzxmw",
"number": 341,
"title": "Automate Zoo Code settings lifecycle and document manual-only integration steps",
"user": {
"login": "tbitcs",
"id": 98970594,
"node_id": "U_kgDOBeYr4g",
"avatar_url": "https://avatars.githubusercontent.com/u/98970594?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/tbitcs",
"html_url": "https://github.com/tbitcs",
"followers_url": "https://api.github.com/users/tbitcs/followers",
"following_url": "https://api.github.com/users/tbitcs/following{/other_user}",
"gists_url": "https://api.github.com/users/tbitcs/gists{/gist_id}",
"starred_url": "https://api.github.com/users/tbitcs/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/tbitcs/subscriptions",
"organizations_url": "https://api.github.com/users/tbitcs/orgs",
"repos_url": "https://api.github.com/users/tbitcs/repos",
"events_url": "https://api.github.com/users/tbitcs/events{/privacy}",
"received_events_url": "https://api.github.com/users/tbitcs/received_events",
"type": "User",
"user_view_type": "public",
"site_admin": false
},
"labels": [
],
"state": "open",
"locked": false,
"assignees": [
],
"milestone": null,
"comments": 0,
"created_at": "2026-07-16T18:48:30Z",
"updated_at": "2026-07-16T18:49:22Z",
"closed_at": null,
"assignee": null,
"author_association": "CONTRIBUTOR",
"issue_field_values": [
],
"type": null,
"active_lock_reason": null,
"sub_issues_summary": {
"total": 0,
"completed": 0,
"percent_completed": 0
},
"issue_dependencies_summary": {
"blocked_by": 0,
"total_blocked_by": 0,
"blocking": 0,
"total_blocking": 0
},
"body": "## Objective\n\nMake Specsmith automatically configure every Zoo Code setting required for governed operation whenever Zoo exposes a stable machine-editable interface. When a setting can only be changed manually, detect that limitation, report the exact remaining action to the user, and document it in both the main repository and Read the Docs.\n\nThis is a child of #335 and coordinates #329, #330, #331, #339, and #340. It follows the test contract in #337.\n\n## Current-state assessment\n\nSpecsmith already has a Zoo Code integration lifecycle that manages reusable global rules, commands, skills, and the repo-local `.roo/mcp.json`. The existing RTD page is `docs/site/zoo-code-roo.md`, and `mkdocs.yml` already exposes it under Agentic Runtime → Agentic Client → Zoo Code / Roo Code.\n\nHowever, Zoo Code also stores important behavior in extension/global settings, including:\n\n- `autoCondenseContext` and `autoCondenseContextPercent`;\n- `customCondensingPrompt`;\n- `enableCheckpoints` and checkpoint timeout;\n- `alwaysAllowMcp`, `alwaysAllowExecute`, and command allow/deny lists;\n- provider profiles and per-profile thresholds;\n- MCP enablement;\n- custom modes and prompts;\n- terminal-output/context settings.\n\nThe current Specsmith setup does not provide a complete settings ownership inventory, automated mutation plan, manual-only fallback report, or drift reconciliation for these settings.\n\n## Core policy\n\n1. **Automate by default.** If Zoo exposes a stable documented file, command, API, VS Code setting, extension storage adapter, or import format, Specsmith should configure it automatically.\n2. **Do not automate by guessing.** Never edit undocumented opaque extension storage directly unless the format and lifecycle are explicitly supported and tested.\n3. **Explain manual-only steps exactly.** When automation is unavailable, setup and doctor must show the precise UI path, setting name, required value, reason, verification step, and whether restart/reload is required.\n4. **Preserve user-owned settings.** Modify only required Specsmith-managed keys. Back up or transactionally merge settings, and never overwrite unrelated profiles, modes, MCP servers, prompts, or user preferences.\n5. **Make state explainable.** For every desired Zoo setting, report `managed`, `already-compliant`, `manual-required`, `unsupported-version`, `conflict`, or `not-applicable`.\n6. **Fail closed for governance-critical gaps.** A manual-only setting that is required for #340 must prevent “fully governed” status until verified.\n\n## Settings capability registry\n\nCreate a versioned registry describing each Zoo integration setting:\n\n```yaml\nsettings:\n context.auto_condense:\n desired: false\n required_for: governed-context\n discovery:\n - zoo-settings-api\n - vscode-settings\n - import-export\n automation: preferred\n verification: runtime-probe\n manual:\n ui_path: Settings > Context Management\n label: Auto Condense Context\n expected: Off\n reload_required: false\n```\n\nEach entry must include:\n\n- semantic Specsmith key;\n- applicable Zoo versions;\n- native Zoo key(s);\n- desired/default value;\n- whether required or recommended;\n- permitted automation mechanisms;\n- read-back verification method;\n- conflict policy;\n- rollback behavior;\n- manual instructions;\n- restart/reload requirement;\n- associated issue/test IDs.\n\nAvoid hard-coding scattered setting mutations throughout the integration module.\n\n## Required automation workflow\n\n`specsmith zoo-code setup` must:\n\n1. detect Zoo/Roo installation and version where possible;\n2. inventory available configuration surfaces;\n3. resolve desired values through #339 global/project/local configuration;\n4. apply all safely automatable settings;\n5. preserve unrelated user state;\n6. read back and verify applied values;\n7. create a machine-readable integration state manifest;\n8. output only remaining manual actions;\n9. state whether the integration is fully governed, partially configured, or unmanaged;\n10. recommend/reload the VS Code window only when necessary.\n\n`specsmith zoo-code doctor` must:\n\n- compare desired, detected, and applied values;\n- identify drift and version incompatibility;\n- automatically repair safe managed drift when `--fix` is used;\n- produce exact manual steps for unfixable gaps;\n- distinguish required failures from recommendations;\n- expose JSON output suitable for agents and CI.\n\nSuggested commands/options:\n\n```text\nspecsmith zoo-code setup --project-dir .\nspecsmith zoo-code setup --dry-run\nspecsmith zoo-code setup --json\nspecsmith zoo-code doctor --project-dir .\nspecsmith zoo-code doctor --fix\nspecsmith zoo-code settings show\nspecsmith zoo-code settings explain <key>\nspecsmith zoo-code settings export-instructions\n```\n\n## Manual-action contract\n\nWhen manual configuration is unavoidable, print a structured block such as:\n\n```text\nMANUAL ACTION REQUIRED: Disable Zoo Code Auto Condense\nReason: Zoo version 1.x does not expose this setting through a supported configuration API.\nRequired for: Specsmith governed context (#340)\n\n1. Open VS Code.\n2. Open Zoo Code.\n3. Select Settings.\n4. Open Context Management.\n5. Turn “Auto Condense Context” off.\n6. Reload the VS Code window only if Zoo requests it.\n7. Run: specsmith zoo-code doctor --project-dir .\n\nVerification: doctor must report context.auto_condense = compliant.\nUntil verified: integration status is PARTIALLY CONFIGURED; governed-context assurances are disabled.\n```\n\nRequirements:\n\n- use exact current UI labels for the detected Zoo version;\n- never say only “change this in settings”;\n- include keyboard-command-palette alternatives where useful;\n- include screenshots only when maintainable, with text instructions remaining authoritative;\n- avoid exposing secrets;\n- provide copyable values;\n- localize only when reliable; English instructions are the baseline.\n\n## Settings required for #340\n\nAt minimum, the registry/setup must manage or explicitly instruct for:\n\n- Zoo native autonomous semantic auto-condense disabled/bypassed;\n- Zoo default/custom CONDENSE prompt not used in healthy governed mode;\n- Zoo sliding-window fallback behavior gated by the Specsmith adapter;\n- MCP enabled and `specsmith-governance` installed;\n- Specsmith context MCP tools allowed for all governed modes;\n- all Specsmith custom modes routed through the context controller;\n- workspace checkpoints labeled/configured separately from semantic checkpoints;\n- profile thresholds coordinated so Specsmith receives telemetry before Zoo reaches a hard limit;\n- required executable/MCP permissions;\n- unmanaged opt-out clearly represented.\n\n## Provider/profile settings\n\nCoordinate with #331:\n\n- automatically create/update the Specsmith-managed local-LLM LiteLLM profile where Zoo's supported import/config mechanism allows it;\n- preserve user-created profiles;\n- do not write secrets directly into exportable settings;\n- use environment/keychain references where supported;\n- when API keys or UI-only secure fields require manual input, provide exact instructions and a verification probe that does not reveal the key;\n- detect endpoint reachability and model aliases separately from configuration presence.\n\n## Ownership and rollback\n\n- Record every key Specsmith changed and its prior value in a local managed-state manifest.\n- `uninstall` should restore prior values only when the current value still equals the Specsmith-managed value; otherwise preserve user modifications and report them.\n- Setup must be idempotent.\n- Upgrades must migrate registry/schema versions deterministically.\n- Concurrent VS Code/Specsmith writes must use conflict detection rather than blind overwrite.\n- Global, project, and profile settings must not be confused.\n\n## Documentation requirements\n\n### Main repository\n\nUpdate or add a prominent integration document in the repository, preferably:\n\n- `docs/site/zoo-code-roo.md` as the canonical user guide used by RTD;\n- a concise link/summary in `README.md` under Integrations or Agent Integrations;\n- optional developer architecture notes under `docs/` if the adapter/settings registry needs deeper implementation documentation.\n\nThe Zoo guide must document:\n\n1. supported Zoo/Roo versions;\n2. architecture and ownership boundary;\n3. what Specsmith configures automatically;\n4. what may require manual configuration;\n5. exact setup and doctor commands;\n6. governed-context behavior from #340;\n7. semantic checkpoint vs workspace snapshot terminology;\n8. local model/LiteLLM profile setup;\n9. global/project/local configuration ownership from #339;\n10. troubleshooting and recovery;\n11. uninstall/rollback behavior;\n12. privacy/secrets behavior;\n13. managed vs unmanaged status indicators.\n\n### Read the Docs\n\n- Keep the page under the existing `mkdocs.yml` Agentic Runtime → Agentic Client integration area.\n- Ensure navigation title remains clear: `Zoo Code / Roo Code`.\n- Add cross-links from `agent-integrations.md`, `configuration.md`, `doctor.md`, and relevant context/ESDB pages.\n- Validate internal links and build the docs in CI.\n- The RTD page and repository source must be the same canonical Markdown, not separately maintained copies.\n\n## Machine-readable status\n\nProduce status such as:\n\n```json\n{\n \"integration\": \"zoo-code\",\n \"zoo_version\": \"...\",\n \"status\": \"partial_manual_required\",\n \"governed_context\": false,\n \"settings\": [\n {\n \"key\": \"context.auto_condense\",\n \"desired\": false,\n \"actual\": true,\n \"state\": \"manual-required\",\n \"required\": true,\n \"instructions_id\": \"ZOO-MANUAL-CONTEXT-001\"\n }\n ]\n}\n```\n\nThis output should be consumable by agents without parsing prose.\n\n## Named tests and binary pass/fail conditions\n\n### ZSET-001 — Safe automatic configuration\n\n**Pass:** setup modifies every supported required key, preserves unrelated settings, reads back the values, and reports no unnecessary manual actions.\n\n**Fail:** required supported keys remain unset or unrelated user state changes.\n\n### ZSET-002 — Idempotent setup\n\n**Pass:** a second setup run produces zero semantic changes and identical managed-state output.\n\n**Fail:** repeated runs create duplicates, rewrite files, or reset user values.\n\n### ZSET-003 — Manual-only instruction quality\n\n**Pass:** an unsupported/UI-only fixture produces exact UI path, label, value, reason, verification command, reload requirement, and governed-status impact.\n\n**Fail:** instructions are vague, incomplete, or cannot be verified.\n\n### ZSET-004 — Required manual gap fails closed\n\n**Pass:** an unverified manual-only governance-critical setting results in `partial_manual_required` and no full #340 assurance.\n\n**Fail:** setup/doctor reports healthy governed mode despite the gap.\n\n### ZSET-005 — Version-specific mapping\n\n**Pass:** supported Zoo versions resolve the correct native key/UI label, and unknown versions produce a bounded unsupported-version result.\n\n**Fail:** Specsmith blindly writes an old key or presents stale instructions.\n\n### ZSET-006 — User-setting preservation\n\n**Pass:** custom profiles, unrelated MCP servers, prompts, modes, and preferences remain byte/semantically unchanged.\n\n**Fail:** setup replaces or removes unmanaged state.\n\n### ZSET-007 — Drift detection and repair\n\n**Pass:** changing a managed value is detected; `doctor --fix` repairs automatable drift and prints manual instructions otherwise.\n\n**Fail:** drift is missed or repaired through an unsupported mechanism.\n\n### ZSET-008 — Secrets\n\n**Pass:** secret values are never printed, committed, added to the managed manifest, or copied into non-secret Zoo settings.\n\n**Fail:** any credential leaks through logs/config/docs/tests.\n\n### ZSET-009 — Uninstall rollback\n\n**Pass:** uninstall restores recorded prior values when safe, preserves post-setup user edits, and removes only Specsmith-owned state.\n\n**Fail:** user changes are overwritten or unrelated state is removed.\n\n### ZSET-010 — Concurrent-write conflict\n\n**Pass:** an external settings change between read and write causes an explicit conflict/retry rather than silent overwrite.\n\n**Fail:** last writer silently wins.\n\n### ZSET-011 — Governed-context settings\n\n**Pass:** all #340-required settings are compliant or explicitly manual-blocked, and instrumentation proves Zoo native summarization is not reachable in a healthy governed session.\n\n**Fail:** settings appear configured while Zoo retains autonomous semantic control.\n\n### ZSET-012 — Provider profile automation\n\n**Pass:** the Specsmith LiteLLM profile is created/updated through a supported mechanism without exposing credentials and without altering user profiles.\n\n**Fail:** setup requires avoidable manual profile entry or overwrites profiles.\n\n### ZSET-013 — Cross-platform paths\n\n**Pass:** Linux, Windows, and macOS discover and modify only the correct supported config surfaces.\n\n**Fail:** path assumptions cause missed or wrong-user writes.\n\n### ZSET-014 — Repository documentation\n\n**Pass:** README links to the canonical Zoo guide and accurately distinguishes automatic and manual configuration.\n\n**Fail:** integration behavior exists without discoverable repository documentation.\n\n### ZSET-015 — RTD integration documentation\n\n**Pass:** `docs/site/zoo-code-roo.md` is in `mkdocs.yml`, cross-links resolve, and the documentation build succeeds.\n\n**Fail:** RTD omits the guide, uses stale duplicated content, or contains broken links.\n\n### ZSET-016 — Instruction verification loop\n\n**Pass:** after the user completes a manual step, doctor detects the compliant value and clears the action without requiring hidden state.\n\n**Fail:** the user cannot prove completion or the warning remains incorrectly.\n\n## Acceptance criteria\n\n- [ ] Every relevant Zoo setting has a registry entry and ownership classification.\n- [ ] Setup automatically applies all safely supported settings.\n- [ ] Manual-only requirements produce exact, version-aware, verifiable instructions.\n- [ ] Governance-critical manual gaps block full governed status.\n- [ ] Doctor detects drift and supports safe repair.\n- [ ] Setup/upgrade/uninstall preserve user-owned settings and secrets.\n- [ ] #340 context-controller requirements are represented explicitly.\n- [ ] `docs/site/zoo-code-roo.md` is expanded as the canonical repository/RTD guide.\n- [ ] README and related RTD pages cross-link to the guide.\n- [ ] ZSET-001 through ZSET-016 pass with #337 machine-readable evidence.\n\n## Non-goals\n\n- Do not edit opaque undocumented Zoo extension databases merely to avoid a manual step.\n- Do not promise automation where Zoo exposes no stable integration surface.\n- Do not maintain separate README and RTD copies of the full guide.\n- Do not store Zoo/provider credentials in tracked Specsmith configuration.\n- Do not silently claim the integration is governed when required settings cannot be verified.\n\n## Agent execution notes\n\nFirst create a complete matrix of Zoo settings, storage surfaces, supported versions, and ownership. Prefer official import/export or extension APIs over direct storage edits. Add read-back verification before enabling automatic writes. Implement the registry and dry-run report before mutation. Treat documentation and manual instructions as tested product behavior, not an afterthought.",
"closed_by": null,
"reactions": {
"url": "https://api.github.com/repos/layer1labs/specsmith/issues/341/reactions",
"total_count": 0,
"+1": 0,
"-1": 0,
"laugh": 0,
"hooray": 0,
"confused": 0,
"heart": 0,
"rocket": 0,
"eyes": 0
},
"timeline_url": "https://api.github.com/repos/layer1labs/specsmith/issues/341/timeline",
"performed_via_github_app": {
"id": 1144995,
"client_id": "Iv23liVemv8A9if9v0F2",
"slug": "chatgpt-codex-connector",
"node_id": "A_kwHOAOQ6Gs4AEXij",
"owner": {
"login": "openai",
"id": 14957082,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjE0OTU3MDgy",
"avatar_url": "https://avatars.githubusercontent.com/u/14957082?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/openai",
"html_url": "https://github.com/openai",
"followers_url": "https://api.github.com/users/openai/followers",
"following_url": "https://api.github.com/users/openai/following{/other_user}",
"gists_url": "https://api.github.com/users/openai/gists{/gist_id}",
"starred_url": "https://api.github.com/users/openai/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/openai/subscriptions",
"organizations_url": "https://api.github.com/users/openai/orgs",
"repos_url": "https://api.github.com/users/openai/repos",
"events_url": "https://api.github.com/users/openai/events{/privacy}",
"received_events_url": "https://api.github.com/users/openai/received_events",
"type": "Organization",
"user_view_type": "public",
"site_admin": false
},
"name": "ChatGPT Codex Connector",
"description": "Bring ChatGPT and Codex to your GitHub repositories.",
"external_url": "https://www.chatgpt.com",
"html_url": "https://github.com/apps/chatgpt-codex-connector",
"created_at": "2025-02-14T01:37:05Z",
"updated_at": "2026-04-20T16:37:15Z",
"permissions": {
"actions": "write",
"checks": "read",
"contents": "write",
"emails": "read",
"issues": "write",
"metadata": "read",
"pull_requests": "write",
"statuses": "read",
"workflows": "write"
},
"events": [
"check_run",
"check_suite",
"commit_comment",
"issues",
"issue_comment",
"pull_request",
"pull_request_review",
"pull_request_review_comment",
"pull_request_review_thread",
"repository",
"status",
"sub_issues"
]
},
"state_reason": null,
"pinned_comment": null
},
{
"url": "https://api.github.com/repos/layer1labs/specsmith/issues/340",
"repository_url": "https://api.github.com/repos/layer1labs/specsmith",
"labels_url": "https://api.github.com/repos/layer1labs/specsmith/issues/340/labels{/name}",
"comments_url": "https://api.github.com/repos/layer1labs/specsmith/issues/340/comments",
"events_url": "https://api.github.com/repos/layer1labs/specsmith/issues/340/events",
"html_url": "https://github.com/layer1labs/specsmith/issues/340",
"id": 4905015118,
"node_id": "I_kwDOR2RC5c8AAAABJFyXTg",
"number": 340,
"title": "Make Specsmith the authoritative Zoo Code checkpoint and context controller",
"user": {
"login": "tbitcs",
"id": 98970594,
"node_id": "U_kgDOBeYr4g",
"avatar_url": "https://avatars.githubusercontent.com/u/98970594?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/tbitcs",
"html_url": "https://github.com/tbitcs",
"followers_url": "https://api.github.com/users/tbitcs/followers",
"following_url": "https://api.github.com/users/tbitcs/following{/other_user}",
"gists_url": "https://api.github.com/users/tbitcs/gists{/gist_id}",
"starred_url": "https://api.github.com/users/tbitcs/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/tbitcs/subscriptions",
"organizations_url": "https://api.github.com/users/tbitcs/orgs",
"repos_url": "https://api.github.com/users/tbitcs/repos",
"events_url": "https://api.github.com/users/tbitcs/events{/privacy}",
"received_events_url": "https://api.github.com/users/tbitcs/received_events",
"type": "User",
"user_view_type": "public",
"site_admin": false
},
"labels": [
],
"state": "open",
"locked": false,
"assignees": [
],
"milestone": null,
"comments": 1,
"created_at": "2026-07-16T18:45:05Z",
"updated_at": "2026-07-16T18:49:30Z",
"closed_at": null,
"assignee": null,
"author_association": "CONTRIBUTOR",
"issue_field_values": [
],
"type": null,
"active_lock_reason": null,
"sub_issues_summary": {
"total": 0,
"completed": 0,
"percent_completed": 0
},
"issue_dependencies_summary": {
"blocked_by": 0,
"total_blocked_by": 0,
"blocking": 0,
"total_blocking": 0
},
"body": "## Objective\n\nIn Specsmith-governed Zoo Code sessions, make Specsmith the authoritative controller for semantic checkpoints, context-pressure decisions, condensation preparation, ESDB offloading, context-packet construction, rehydration, health validation, and resume integrity.\n\nZoo Code may remain the mechanical sensor/actuator because it owns the live message array, exact provider token accounting, API request assembly, UI, and optional shadow-Git workspace snapshot implementation. Zoo must not independently decide what semantic state survives or generate an ungoverned conversation summary.\n\nThis ticket coordinates #332, #333, #334, #336, #338, and #339 and is a child of #335. It follows the test contract in #337.\n\n## Findings from current implementations\n\n### Zoo Code currently owns too much semantic context behavior\n\nZoo currently:\n\n- calculates context pressure and condensation thresholds;\n- invokes its own LLM summarization prompt;\n- chooses what conversation content and folded file context enters the summary;\n- inserts the generated summary as the sole fresh-start message;\n- falls back to sliding-window truncation when summarization fails;\n- exposes independent `autoCondenseContext`, threshold, custom-condensing-prompt, and checkpoint settings.\n\nThis means a custom Specsmith prompt alone is not enough. Zoo would still own the decision, input selection, summary execution, fallback behavior, and final active-context replacement.\n\n### Specsmith already has the beginnings of the correct control plane\n\nSpecsmith already has:\n\n- a `ContextOrchestrator` with pressure tiers and ESDB awareness;\n- a durable chat handoff mechanism;\n- a Zoo-generated `specsmith-checkpoint` command;\n- an MCP `governance_checkpoint` tool;\n- ESDB/context residency, health, distributed merge, identity, and configuration tickets.\n\nHowever, the existing MCP checkpoint is only a compact governance anchor. It does not yet capture the complete active task state, exact constraints, decisions, evidence, commands/results, context selection, integrity digest, or replacement packet required for authoritative context management.\n\nThe current context orchestrator also directly summarizes/trims history and incorrectly tombstones some records during context eviction. Those behaviors must be replaced through #333/#334 rather than used as the final integration contract.\n\n## Required ownership boundary\n\n### Specsmith owns\n\n- context policy and thresholds;\n- task-fit prediction and checkpoint timing;\n- semantic checkpoint generation;\n- checkpoint schema, IDs, hashes, provenance, and ESDB persistence;\n- authority ranking and pinned invariants;\n- selection of information to keep resident, reference, offload, or exclude;\n- conflict/staleness/contamination checks;\n- generation of the bounded replacement context packet;\n- post-condensation validation and resume authorization;\n- fresh-task handoff contents and continuity validation;\n- audit evidence for all context lifecycle decisions.\n\n### Zoo Code owns only the adapter/mechanical layer\n\n- exact live token and provider-window telemetry;\n- live message/tool-result capture;\n- invoking Specsmith MCP/context APIs;\n- pausing task execution while a context transition is pending;\n- replacing or filtering the effective API history using the exact packet Specsmith returns;\n- displaying checkpoint/health/transition state in the UI;\n- preserving raw task history for UI rewind where desired;\n- emergency mechanical handling when the model API cannot accept another request;\n- optional workspace snapshots/rollback, clearly distinguished from semantic checkpoints.\n\n### Terminology must be explicit\n\nUse separate names:\n\n- **Semantic checkpoint**: Specsmith-authored epistemic/task continuity record.\n- **Context packet**: Specsmith-authored bounded input replacing older active context.\n- **Workspace snapshot**: Zoo/shadow-Git filesystem rollback point.\n- **Conversation rewind**: Zoo UI/history operation.\n\nZoo's existing native “checkpoint” must never be presented as equivalent to a Specsmith semantic checkpoint.\n\n## Governed-mode protocol\n\nImplement a protocol such as:\n\n1. Zoo emits `ContextTelemetry` to Specsmith before each nontrivial turn and after material tool results.\n2. Specsmith returns a signed/hashed `ContextDirective`:\n - `continue`;\n - `checkpoint`;\n - `checkpoint_and_compact`;\n - `replace_context`;\n - `spawn_fresh_task`;\n - `block_for_conflict`;\n - `emergency_minimal_packet`.\n3. When checkpointing is required, Zoo supplies the required raw inputs/tool results to Specsmith.\n4. Specsmith constructs and persists the semantic checkpoint in ESDB.\n5. Specsmith generates a bounded `ContextPacket` with stable references and integrity digest.\n6. Zoo replaces effective model context with that exact packet, without running its own summary LLM call.\n7. Zoo reports the applied packet digest and resulting token count.\n8. Specsmith validates the transition and returns `resume_allowed=true|false`.\n9. Work resumes only when integrity and health gates pass.\n\nExample directive:\n\n```json\n{\n \"schema_version\": 1,\n \"directive_id\": \"CTXDIR-...\",\n \"action\": \"replace_context\",\n \"reason\": \"predicted task envelope exceeds safe headroom\",\n \"checkpoint_required\": true,\n \"checkpoint_id\": \"CHK-...\",\n \"packet_id\": \"CTXPKT-...\",\n \"expected_packet_digest\": \"sha256:...\",\n \"resume_requires_validation\": true\n}\n```\n\n## Zoo configuration behavior\n\nWhen Specsmith governed-context mode is enabled:\n\n- disable Zoo autonomous semantic auto-condense;\n- disable Zoo custom/default condensation prompt execution;\n- prevent Zoo from independently inserting a generated conversation summary;\n- disable ordinary sliding-window truncation as a normal fallback;\n- configure all Specsmith Zoo modes to use the Specsmith context controller;\n- preserve native Zoo workspace snapshots only as optional rollback functionality;\n- mark any emergency Zoo fallback as degraded and require immediate Specsmith reconciliation before further work.\n\nDo not merely set `customCondensingPrompt` to a Specsmith-themed prompt. That leaves Zoo in control and is not sufficient.\n\nIf Zoo currently lacks an external context-controller hook, provide:\n\n1. an upstream Zoo Code change/PR specification; and\n2. a temporary compatibility mode that triggers Specsmith early enough to avoid Zoo's native threshold, while failing closed rather than silently reverting to Zoo semantic summarization.\n\n## Specsmith APIs/MCP tools\n\nAdd or evolve tools such as:\n\n```text\ncontext_observe\ncontext_preflight\ncontext_checkpoint_create\ncontext_packet_build\ncontext_packet_get\ncontext_transition_validate\ncontext_health\ncontext_rehydrate\ncontext_spawn_handoff\n```\n\nThe old `governance_checkpoint` may remain as a lightweight status anchor, but it must call or reference the authoritative semantic checkpoint subsystem rather than being the sole checkpoint implementation.\n\n### `context_observe` inputs\n\nAt minimum:\n\n- task/session/mode/profile IDs;\n- model/provider/context-window/output reserve;\n- exact current input tokens;\n- recent token growth;\n- turn count and meaningful-event count;\n- current user request;\n- active files and tool-result references;\n- current Zoo task ID;\n- current applied packet/checkpoint IDs;\n- unresolved errors/retries;\n- identity and replica information from #338.\n\n### Semantic checkpoint contents\n\nAt minimum:\n\n- exact current objective and latest user instruction;\n- accepted scope and exclusions;\n- immutable constraints and authority sources;\n- current proposal/plan;\n- decisions and rationale;\n- requirements/tests/acceptance criteria;\n- changed and relevant files with digests/refs;\n- commands, results, failures, and verification evidence;\n- unresolved questions, contradictions, risks, and hypotheses;\n- rejected paths and why;\n- current task/subtask graph;\n- exact next action;\n- identity/delegation/session/replica provenance;\n- context health report;\n- source references and packet selection explanation;\n- checkpoint/event-set digest.\n\n### Context packet rules\n\nThe packet must be:\n\n- generated by Specsmith, not Zoo's condensing LLM;\n- bounded by a token budget supplied by Zoo;\n- schema-validated;\n- authority-aware and provenance-preserving;\n- deterministic where inputs and model-free policies permit;\n- explicit about summaries versus exact quoted/reference material;\n- able to reference ESDB records instead of embedding all history;\n- validated against the checkpoint before use;\n- rejected if critical invariants cannot fit or be safely referenced.\n\n## Emergency behavior\n\nZoo must retain enough mechanical protection to avoid a provider hard failure, but emergency behavior cannot become a second semantic authority.\n\nRequired order:\n\n1. call Specsmith early using predictive thresholds from #332;\n2. if Specsmith is temporarily unavailable, pause and retry within a bounded policy;\n3. if the provider request would otherwise be impossible, use a minimal mechanically safe action that preserves raw history;\n4. mark the session `context_state=degraded_unreconciled`;\n5. block code changes, external writes, release actions, and completion claims;\n6. require Specsmith reconstruction/validation before normal operation resumes.\n\nZoo must never silently use its default summary/truncation and continue as healthy.\n\n## Workspace checkpoints\n\nZoo's native shadow-Git checkpoint capability can remain enabled for file rollback if useful, but:\n\n- it must be labeled `workspace snapshot` in Specsmith integration/UI;\n- semantic checkpoint creation may request a paired workspace snapshot ID;\n- the semantic checkpoint stores the workspace snapshot reference;\n- restoring a workspace snapshot triggers a new Specsmith context-health/reconciliation pass;\n- a workspace restore never rewinds or deletes ESDB evidence automatically.\n\n## Named tests and binary pass/fail conditions\n\n### ZCTX-001 — Specsmith checkpoint authority\n\n**Pass:** a checkpoint request in governed mode invokes Specsmith, produces a persisted semantic checkpoint ID/digest, and Zoo does not generate an independent checkpoint summary.\n\n**Fail:** Zoo's default/custom summarizer creates the authoritative continuity state.\n\n### ZCTX-002 — Specsmith-controlled condensation\n\n**Pass:** at the configured pressure boundary, Specsmith selects the action and returns the exact replacement packet applied by Zoo.\n\n**Fail:** Zoo independently chooses condensation timing, content, or summary.\n\n### ZCTX-003 — Native auto-condense disabled\n\n**Pass:** governed setup disables/bypasses Zoo's autonomous condensation path for every Specsmith mode and `doctor` verifies it.\n\n**Fail:** any governed mode can reach Zoo's normal `summarizeConversation` path without an explicit degraded emergency event.\n\n### ZCTX-004 — No silent sliding-window fallback\n\n**Pass:** a failed Specsmith transition pauses or enters degraded blocked state while preserving history.\n\n**Fail:** Zoo truncates half the conversation and continues as healthy.\n\n### ZCTX-005 — Exact packet integrity\n\n**Pass:** Zoo reports the applied packet digest and Specsmith verifies it before resume.\n\n**Fail:** the packet is altered, supplemented with an unapproved summary, or resumed without validation.\n\n### ZCTX-006 — Required state survival\n\nA fixture includes exact user constraints, accepted decision, failed command, file digest, unresolved contradiction, and next action.\n\n**Pass:** all required invariants are present or stably referenced after context replacement.\n\n**Fail:** any invariant is omitted, weakened, or converted from exact evidence into unsupported inference.\n\n### ZCTX-007 — Context health gate\n\n**Pass:** a contaminated or contradictory packet returns `resume_allowed=false` until #334 cleanup/resolution completes.\n\n**Fail:** Zoo continues because its local summary looks syntactically valid.\n\n### ZCTX-008 — ESDB offload and rehydration\n\n**Pass:** old material leaves active context but remains durable and can be loaded by stable ID through #333.\n\n**Fail:** records are tombstoned/deleted or raw history is blindly reinserted.\n\n### ZCTX-009 — Specsmith unavailable\n\n**Pass:** Zoo preserves raw history, enters explicit degraded state, blocks consequential work, and reconciles before resuming.\n\n**Fail:** native summary/truncation silently takes over.\n\n### ZCTX-010 — Provider hard-limit emergency\n\n**Pass:** emergency handling avoids the failed request, records a degraded event, preserves recoverability, and prevents normal claims/actions until validated.\n\n**Fail:** data is silently discarded or the session remains marked healthy.\n\n### ZCTX-011 — Manual condense action\n\n**Pass:** a user pressing Zoo's condense action in governed mode routes to Specsmith's checkpoint/packet workflow.\n\n**Fail:** the button invokes Zoo's built-in LLM summarizer.\n\n### ZCTX-012 — Workspace snapshot distinction\n\n**Pass:** native Zoo checkpoint creates/restores a workspace snapshot paired to, but distinct from, a Specsmith semantic checkpoint; restore triggers reconciliation.\n\n**Fail:** workspace rollback is treated as epistemic/context rollback or deletes evidence.\n\n### ZCTX-013 — Multi-mode/profile coverage\n\n**Pass:** orchestrator, architect, code, debug, ask, reviewer, and all Specsmith custom modes use the same context-controller contract.\n\n**Fail:** any mode falls back to unmanaged Zoo context behavior.\n\n### ZCTX-014 — Fresh-task handoff\n\n**Pass:** when Specsmith selects `spawn_fresh_task`, Zoo creates the task from the exact governed handoff packet and reports the new task ID for validation.\n\n**Fail:** Zoo creates a task from its own summary or loses task identity/provenance.\n\n### ZCTX-015 — Rewind/edit reconciliation\n\n**Pass:** Zoo conversation rewind/edit invalidates affected applied packets/checkpoints and requires Specsmith reconciliation before continuing.\n\n**Fail:** stale checkpoint authority remains active after history changes.\n\n### ZCTX-016 — Test double proves Zoo summarizer unused\n\n**Pass:** instrumented tests fail if Zoo's `summarizeConversation` or default `CONDENSE` prompt is called in a healthy governed session.\n\n**Fail:** the test suite cannot distinguish Specsmith-controlled context from themed Zoo summarization.\n\n### ZCTX-017 — Cross-platform adapter\n\n**Pass:** Linux, Windows, and macOS produce equivalent directives, packet digests, MCP behavior, and blocked/degraded semantics.\n\n**Fail:** shell/path/platform differences bypass governance or alter semantic results.\n\n### ZCTX-018 — Ungoverned opt-out\n\n**Pass:** users may explicitly disable Specsmith governed-context mode, after which Zoo native behavior is clearly reported as unmanaged and no Specsmith assurance is claimed.\n\n**Fail:** unmanaged sessions are represented as Specsmith-governed.\n\n## Acceptance criteria\n\n- [ ] Specsmith is the only semantic checkpoint generator in governed mode.\n- [ ] Specsmith decides context transitions and generates the exact context packet.\n- [ ] Zoo's normal summarization and sliding-window policies cannot silently run in healthy governed mode.\n- [ ] Zoo remains the live telemetry/message/UI actuator and optional workspace-snapshot provider.\n- [ ] Specsmith validates every applied packet before consequential work resumes.\n- [ ] Emergency fallback is explicit, recoverable, degraded, and blocking.\n- [ ] Existing `governance_checkpoint` evolves into or references the full semantic checkpoint subsystem.\n- [ ] ZCTX-001 through ZCTX-018 exist and pass with #337 machine-readable evidence.\n- [ ] Setup, doctor, export/import, migration, and uninstall preserve user-owned Zoo settings and clearly report governed/unmanaged state.\n\n## Non-goals\n\n- Do not fork all of Zoo's provider, UI, or message persistence logic into Specsmith.\n- Do not treat a custom Zoo condensing prompt as authoritative Specsmith control.\n- Do not disable useful workspace rollback merely because semantic checkpoints move to Specsmith.\n- Do not allow two independent context managers to race.\n- Do not claim perfect control where Zoo lacks the required adapter hook; fail closed and document the upstream dependency.\n\n## Agent execution notes\n\nStart with an architecture decision record and a sequence diagram. Instrument Zoo's current condense/truncation/checkpoint entry points before changing behavior. Build the Specsmith MCP/controller contract and deterministic fixtures first. Then add the Zoo adapter and hard tests proving native summarization is not invoked in healthy governed mode.",
"closed_by": null,
"reactions": {
"url": "https://api.github.com/repos/layer1labs/specsmith/issues/340/reactions",
"total_count": 0,
"+1": 0,
"-1": 0,
"laugh": 0,
"hooray": 0,
"confused": 0,
"heart": 0,
"rocket": 0,
"eyes": 0
},
"timeline_url": "https://api.github.com/repos/layer1labs/specsmith/issues/340/timeline",
"performed_via_github_app": {
"id": 1144995,
"client_id": "Iv23liVemv8A9if9v0F2",
"slug": "chatgpt-codex-connector",
"node_id": "A_kwHOAOQ6Gs4AEXij",
"owner": {
"login": "openai",
"id": 14957082,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjE0OTU3MDgy",
"avatar_url": "https://avatars.githubusercontent.com/u/14957082?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/openai",
"html_url": "https://github.com/openai",
"followers_url": "https://api.github.com/users/openai/followers",
"following_url": "https://api.github.com/users/openai/following{/other_user}",
"gists_url": "https://api.github.com/users/openai/gists{/gist_id}",
"starred_url": "https://api.github.com/users/openai/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/openai/subscriptions",
"organizations_url": "https://api.github.com/users/openai/orgs",
"repos_url": "https://api.github.com/users/openai/repos",
"events_url": "https://api.github.com/users/openai/events{/privacy}",
"received_events_url": "https://api.github.com/users/openai/received_events",
"type": "Organization",
"user_view_type": "public",
"site_admin": false
},
"name": "ChatGPT Codex Connector",
"description": "Bring ChatGPT and Codex to your GitHub repositories.",
"external_url": "https://www.chatgpt.com",
"html_url": "https://github.com/apps/chatgpt-codex-connector",
"created_at": "2025-02-14T01:37:05Z",
"updated_at": "2026-04-20T16:37:15Z",
"permissions": {
"actions": "write",
"checks": "read",
"contents": "write",
"emails": "read",
"issues": "write",
"metadata": "read",
"pull_requests": "write",
"statuses": "read",
"workflows": "write"
},
"events": [
"check_run",
"check_suite",
"commit_comment",
"issues",
"issue_comment",
"pull_request",
"pull_request_review",
"pull_request_review_comment",
"pull_request_review_thread",
"repository",
"status",
"sub_issues"
]
},
"state_reason": null,
"pinned_comment": null
},
{
"url": "https://api.github.com/repos/layer1labs/specsmith/issues/339",
"repository_url": "https://api.github.com/repos/layer1labs/specsmith",
"labels_url": "https://api.github.com/repos/layer1labs/specsmith/issues/339/labels{/name}",
"comments_url": "https://api.github.com/repos/layer1labs/specsmith/issues/339/comments",
"events_url": "https://api.github.com/repos/layer1labs/specsmith/issues/339/events",
"html_url": "https://github.com/layer1labs/specsmith/issues/339",
"id": 4904907577,
"node_id": "I_kwDOR2RC5c8AAAABJFrzOQ",
"number": 339,
"title": "Unify Specsmith global, project, and local configuration schemas",
"user": {
"login": "tbitcs",
"id": 98970594,
"node_id": "U_kgDOBeYr4g",
"avatar_url": "https://avatars.githubusercontent.com/u/98970594?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/tbitcs",
"html_url": "https://github.com/tbitcs",
"followers_url": "https://api.github.com/users/tbitcs/followers",
"following_url": "https://api.github.com/users/tbitcs/following{/other_user}",
"gists_url": "https://api.github.com/users/tbitcs/gists{/gist_id}",
"starred_url": "https://api.github.com/users/tbitcs/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/tbitcs/subscriptions",
"organizations_url": "https://api.github.com/users/tbitcs/orgs",
"repos_url": "https://api.github.com/users/tbitcs/repos",
"events_url": "https://api.github.com/users/tbitcs/events{/privacy}",
"received_events_url": "https://api.github.com/users/tbitcs/received_events",
"type": "User",
"user_view_type": "public",
"site_admin": false
},
"labels": [
],
"state": "open",
"locked": false,
"assignees": [
],
"milestone": null,
"comments": 0,
"created_at": "2026-07-16T18:30:26Z",
"updated_at": "2026-07-16T18:30:57Z",
"closed_at": null,
"assignee": null,
"author_association": "CONTRIBUTOR",
"issue_field_values": [
],
"type": null,
"active_lock_reason": null,
"sub_issues_summary": {
"total": 0,
"completed": 0,
"percent_completed": 0
},
"issue_dependencies_summary": {
"blocked_by": 0,
"total_blocked_by": 0,
"blocking": 0,
"total_blocking": 0
},
"body": "## Objective\n\nCreate one documented, versioned configuration system for Specsmith that cleanly separates:\n\n1. global user and machine preferences;\n2. tracked project policy and metadata;\n3. untracked project-local/machine-local overrides;\n4. environment and command-line overrides.\n\nConsolidate the current fragmented configuration paths without losing backward compatibility. This is required by #338 and #336 and follows the test contract in #337.\n\n## Current-state assessment\n\nSpecsmith already has a substantial Pydantic `ProjectConfig` used for project scaffolding and a canonical tracked project manifest at `docs/SPECSMITH.yml`. However, other code separately reads `.specsmith/governance/config.yaml` and falls back to `.specsmith/config.yml`. There is no single versioned global user configuration schema or centralized precedence/resolution API.\n\nThe result is ambiguity over which file owns project metadata, governance policy, runtime preferences, ESDB settings, Zoo Code settings, identity, and machine-specific values.\n\n## Configuration layers and precedence\n\nDefine one resolver with this precedence, highest first:\n\n1. explicit CLI flags;\n2. environment variables;\n3. untracked project-local config;\n4. tracked project config;\n5. global user config;\n6. built-in defaults.\n\nEvery resolved value must expose its source layer through `config explain`.\n\n## Canonical locations\n\nUse platform-native global config directories:\n\n- Linux: `${XDG_CONFIG_HOME:-~/.config}/specsmith/config.yml`\n- macOS: `~/Library/Application Support/Specsmith/config.yml` unless XDG is explicitly selected\n- Windows: `%APPDATA%\\Specsmith\\config.yml`\n\nProject files:\n\n- `docs/SPECSMITH.yml` — tracked, reviewable project policy and metadata;\n- `.specsmith/local.yml` — untracked local overrides for one checkout/worktree;\n- secrets remain outside these files or use references to environment variables/keyrings.\n\nDo not use `.specsmith/config.yml` as a second ambiguous tracked project schema after migration. Preserve it only as a legacy input until migrated.\n\n## Schema separation\n\nCreate versioned Pydantic models such as:\n\n- `GlobalConfig`\n- `ProjectConfig`\n- `LocalConfig`\n- `ResolvedConfig`\n- nested sections for identity, ESDB, context governance, Zoo Code, providers, verification, paths, telemetry, and privacy.\n\nFields must explicitly declare which layers may set them. For example:\n\n- project name/type/requirements policy: tracked project layer;\n- preferred provider, prompt caching, default identity alias: global layer, locally overridable;\n- replica ID, local endpoint reachability, machine paths: local/global machine state, never tracked project policy;\n- API keys and credentials: secret references only, never plaintext tracked config.\n\n## Required behavior\n\n1. Add a single config loader/resolver used by CLI, governance, ESDB, context orchestration, Zoo integration, and identity resolution.\n2. Add schema versions and deterministic migrations.\n3. Detect duplicate/conflicting legacy files and fail with actionable diagnostics rather than silently selecting an arbitrary value.\n4. Preserve comments where practical; otherwise create backups and provide a migration report.\n5. Add commands:\n\n```text\nspecsmith config paths\nspecsmith config show [--resolved]\nspecsmith config get <key>\nspecsmith config set <key> <value> [--global|--project|--local]\nspecsmith config unset <key> [--global|--project|--local]\nspecsmith config explain <key>\nspecsmith config validate\nspecsmith config migrate\n```\n\n6. `show --resolved` must redact secrets and display source provenance for each value.\n7. Unknown keys must either fail validation or be preserved in an explicitly namespaced extensions section; never silently drop them.\n8. Project config must be deterministic and merge-friendly: stable key ordering, UTF-8, LF normalization, no timestamps or machine-specific paths.\n9. Local config must be automatically added to generated `.gitignore` files.\n10. Global and local writes must be atomic and permission-conscious.\n11. Support configuration profiles only when their semantics are explicit; avoid duplicating Zoo Code profile storage inside Specsmith.\n12. Document which values belong in each layer and provide minimal examples.\n\n## Migration mapping\n\n- canonical scaffold/project fields from `docs/SPECSMITH.yml` remain in the tracked project model;\n- legacy root `scaffold.yml` migrates to `docs/SPECSMITH.yml`;\n- `.specsmith/governance/config.yaml` governance-specific values migrate into a namespaced project section when tracked policy, or local section when machine-specific;\n- `.specsmith/config.yml` is classified field-by-field and migrated to project/global/local as appropriate;\n- conflicts require an explicit report and may not be silently overwritten.\n\n## Named tests and binary pass/fail conditions\n\n### CONFIG-001 — Precedence\n\n**Pass:** CLI > environment > local > project > global > defaults for every tested field, and `config explain` reports the winning source.\n\n**Fail:** a lower layer overrides a higher layer or source reporting is incorrect.\n\n### CONFIG-002 — Platform paths\n\n**Pass:** Linux, macOS, and Windows resolve canonical global paths without embedding another platform's separators or locations.\n\n**Fail:** platform paths differ from the declared policy or require manual path editing.\n\n### CONFIG-003 — Project determinism\n\n**Pass:** writing the same project config twice is byte-identical and produces no Git diff.\n\n**Fail:** ordering, timestamps, newline conversion, or machine values create drift.\n\n### CONFIG-004 — Local isolation\n\n**Pass:** `.specsmith/local.yml` overrides one worktree, is ignored by Git, and does not change another worktree's resolved config.\n\n**Fail:** local state is committed or leaks between worktrees.\n\n### CONFIG-005 — Legacy migration\n\n**Pass:** fixtures containing all legacy config locations migrate without value loss, create a report/backup, and a second migration is zero-diff.\n\n**Fail:** values disappear, move to the wrong layer, or migration is non-idempotent.\n\n### CONFIG-006 — Conflicting legacy values\n\n**Pass:** contradictory values in legacy files produce an explicit conflict requiring resolution.\n\n**Fail:** one value silently wins.\n\n### CONFIG-007 — Secret handling\n\n**Pass:** resolved output redacts secret values, tracked files contain only references, and doctor detects plaintext credentials in tracked config.\n\n**Fail:** credentials appear in output, logs, fixtures, or committed files.\n\n### CONFIG-008 — Unknown keys\n\n**Pass:** unknown keys are rejected with location-aware diagnostics or preserved under a documented extension namespace.\n\n**Fail:** unknown keys are silently ignored or removed.\n\n### CONFIG-009 — Concurrent project edits\n\n**Pass:** two branches changing different project fields merge cleanly; conflicting same-field changes remain normal visible Git conflicts and are never auto-resolved by machine-local precedence.\n\n**Fail:** generated rewrites cause whole-file conflicts or silently choose one branch.\n\n### CONFIG-010 — Consumer parity\n\n**Pass:** CLI, governance store, ESDB, context orchestration, Zoo integration, and identity resolver all receive the same resolved values and provenance.\n\n**Fail:** any subsystem reads a legacy file independently and obtains a different value.\n\n### CONFIG-011 — Atomic writes and recovery\n\n**Pass:** interrupted writes leave either the old or new valid file, with recovery diagnostics and no partial YAML.\n\n**Fail:** truncation or malformed configuration is accepted.\n\n### CONFIG-012 — Manual editing round-trip\n\n**Pass:** a documented hand-edited config validates and survives load/write without semantic changes.\n\n**Fail:** valid user changes are overwritten or normalized into different semantics.\n\n## Acceptance criteria\n\n- [ ] One resolver and precedence model governs all Specsmith configuration consumers.\n- [ ] Versioned global, project, and local schemas exist.\n- [ ] `docs/SPECSMITH.yml` remains the canonical tracked project file.\n- [ ] `.specsmith/local.yml` is the canonical ignored project-local override.\n- [ ] Global paths are platform-native.\n- [ ] Legacy config files migrate deterministically and idempotently.\n- [ ] Secrets are referenced/redacted, not stored in tracked config.\n- [ ] CONFIG-001 through CONFIG-012 exist and pass with machine-readable #337 evidence.\n- [ ] Documentation clearly explains ownership, precedence, paths, and examples.\n\n## Non-goals\n\n- Do not create one giant file containing secrets, runtime databases, and project policy.\n- Do not let global preferences silently override tracked project safety policy unless the field explicitly allows it.\n- Do not duplicate provider secrets or Zoo Code-managed credentials.\n- Do not retain multiple active project config files after migration.\n\n## Agent execution notes\n\nInventory every direct config-file read before implementing. Introduce the resolver first, migrate consumers incrementally, and add a temporary diagnostic for legacy direct reads. Keep configuration semantics separate from ESDB records: config determines policy; ESDB records actions and evidence.",
"closed_by": null,
"reactions": {
"url": "https://api.github.com/repos/layer1labs/specsmith/issues/339/reactions",
"total_count": 0,
"+1": 0,
"-1": 0,
"laugh": 0,
"hooray": 0,
"confused": 0,
"heart": 0,
"rocket": 0,
"eyes": 0
},
"timeline_url": "https://api.github.com/repos/layer1labs/specsmith/issues/339/timeline",
"performed_via_github_app": {
"id": 1144995,
"client_id": "Iv23liVemv8A9if9v0F2",
"slug": "chatgpt-codex-connector",
"node_id": "A_kwHOAOQ6Gs4AEXij",
"owner": {
"login": "openai",
"id": 14957082,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjE0OTU3MDgy",
"avatar_url": "https://avatars.githubusercontent.com/u/14957082?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/openai",
"html_url": "https://github.com/openai",
"followers_url": "https://api.github.com/users/openai/followers",
"following_url": "https://api.github.com/users/openai/following{/other_user}",
"gists_url": "https://api.github.com/users/openai/gists{/gist_id}",
"starred_url": "https://api.github.com/users/openai/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/openai/subscriptions",
"organizations_url": "https://api.github.com/users/openai/orgs",
"repos_url": "https://api.github.com/users/openai/repos",
"events_url": "https://api.github.com/users/openai/events{/privacy}",
"received_events_url": "https://api.github.com/users/openai/received_events",
"type": "Organization",
"user_view_type": "public",
"site_admin": false
},
"name": "ChatGPT Codex Connector",
"description": "Bring ChatGPT and Codex to your GitHub repositories.",
"external_url": "https://www.chatgpt.com",
"html_url": "https://github.com/apps/chatgpt-codex-connector",
"created_at": "2025-02-14T01:37:05Z",
"updated_at": "2026-04-20T16:37:15Z",
"permissions": {
"actions": "write",
"checks": "read",
"contents": "write",
"emails": "read",
"issues": "write",
"metadata": "read",
"pull_requests": "write",
"statuses": "read",
"workflows": "write"
},
"events": [
"check_run",
"check_suite",
"commit_comment",
"issues",
"issue_comment",
"pull_request",
"pull_request_review",
"pull_request_review_comment",
"pull_request_review_thread",
"repository",
"status",
"sub_issues"
]
},
"state_reason": null,
"pinned_comment": null
},
{
"url": "https://api.github.com/repos/layer1labs/specsmith/issues/338",
"repository_url": "https://api.github.com/repos/layer1labs/specsmith",
"labels_url": "https://api.github.com/repos/layer1labs/specsmith/issues/338/labels{/name}",
"comments_url": "https://api.github.com/repos/layer1labs/specsmith/issues/338/comments",
"events_url": "https://api.github.com/repos/layer1labs/specsmith/issues/338/events",
"html_url": "https://github.com/layer1labs/specsmith/issues/338",
"id": 4904905962,
"node_id": "I_kwDOR2RC5c8AAAABJFrs6g",
"number": 338,
"title": "Add layered Specsmith user, agent, and replica identity awareness",
"user": {
"login": "tbitcs",
"id": 98970594,
"node_id": "U_kgDOBeYr4g",
"avatar_url": "https://avatars.githubusercontent.com/u/98970594?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/tbitcs",
"html_url": "https://github.com/tbitcs",
"followers_url": "https://api.github.com/users/tbitcs/followers",
"following_url": "https://api.github.com/users/tbitcs/following{/other_user}",
"gists_url": "https://api.github.com/users/tbitcs/gists{/gist_id}",
"starred_url": "https://api.github.com/users/tbitcs/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/tbitcs/subscriptions",
"organizations_url": "https://api.github.com/users/tbitcs/orgs",
"repos_url": "https://api.github.com/users/tbitcs/repos",
"events_url": "https://api.github.com/users/tbitcs/events{/privacy}",
"received_events_url": "https://api.github.com/users/tbitcs/received_events",
"type": "User",
"user_view_type": "public",
"site_admin": false
},
"labels": [
],
"state": "open",
"locked": false,
"assignees": [
],
"milestone": null,
"comments": 0,
"created_at": "2026-07-16T18:30:13Z",
"updated_at": "2026-07-16T18:31:36Z",
"closed_at": null,
"assignee": null,
"author_association": "CONTRIBUTOR",
"issue_field_values": [
],
"type": null,
"active_lock_reason": null,
"sub_issues_summary": {
"total": 0,
"completed": 0,
"percent_completed": 0
},
"issue_dependencies_summary": {
"blocked_by": 0,
"total_blocked_by": 0,
"blocking": 0,
"total_blocking": 0
},
"body": "## Objective\n\nGive Specsmith stable, explainable awareness of the human user, executing agent, service principal, replica/worktree, and session responsible for every governed action. Auto-detect useful identity signals, persist a global default, allow project-local overrides, and let users inspect or manually change the resolved identity without silently conflating display names with identity.\n\nThis is a focused child of #336 and depends on the layered configuration foundation in #339. It follows the verification contract in #337.\n\n## Identity model\n\nDefine distinct identity dimensions:\n\n- `actor_id`: stable human or service-principal identity responsible for the action;\n- `actor_display_name`: mutable human-readable label;\n- `provider_accounts`: linked external identities such as GitHub, GitLab, Bitbucket, Azure DevOps, or local Git identity;\n- `agent_id`: executing agent/model instance or named automation identity;\n- `delegation`: relationship showing that an agent acted for a human/service actor;\n- `replica_id`: stable machine/worktree writer identity used by distributed ESDB;\n- `session_id`: one bounded execution session;\n- `identity_confidence` and `verification_state`: explain how the identity was resolved.\n\nDo not use email addresses, Git display names, OS usernames, branch names, or provider usernames as the canonical actor ID by themselves.\n\n## Resolution precedence\n\nResolve each identity field independently using the configuration precedence from #339:\n\n1. explicit CLI/session override;\n2. environment override;\n3. project-local identity override;\n4. tracked project identity policy or permitted mapping;\n5. global Specsmith user identity;\n6. verified provider identity auto-detection;\n7. local Git identity;\n8. OS account fallback;\n9. anonymous/generated local identity with a warning.\n\nA lower-confidence source must not silently replace a higher-confidence configured identity.\n\n## Auto-detection providers\n\nSupport pluggable detection, initially including:\n\n- GitHub CLI authenticated user when `gh` is available;\n- repository GitHub remote owner/account context as supporting evidence only;\n- GitLab CLI/account where available;\n- Azure DevOps or other supported VCS identity where available;\n- `git config user.name` and `user.email` as low-confidence supporting metadata;\n- OS username as final low-confidence fallback.\n\nDetection must be read-only, bounded, timeout-safe, and work offline. Missing provider CLIs must not fail normal Specsmith operation.\n\n## Global and local configuration\n\nGlobal config may contain a default identity profile:\n\n```yaml\nidentity:\n actor_id: USER-...\n display_name: Example User\n preferred_profile: default\n provider_links:\n github:\n login: example\n account_id: \"12345\"\n verification: provider-detected\n privacy:\n include_email_in_events: false\n```\n\nProject-local `.specsmith/local.yml` may select or override the active profile for that checkout or worktree without changing the tracked project configuration.\n\nTracked `docs/SPECSMITH.yml` may define identity policy, organization IDs, required trust levels, and allowed actor mappings, but should not force every contributor to share one personal identity.\n\n## Required commands\n\nAdd operations such as:\n\n```text\nspecsmith identity show\nspecsmith identity detect\nspecsmith identity explain\nspecsmith identity list\nspecsmith identity create <name>\nspecsmith identity use <name> [--global|--local]\nspecsmith identity set <field> <value> [--global|--local]\nspecsmith identity link github\nspecsmith identity unlink github\nspecsmith identity verify\nspecsmith identity rotate-replica\n```\n\n`show` and `explain` must display the resolved source, confidence, verification state, delegation, replica, and session identity while redacting private data according to policy.\n\n## Stable ID requirements\n\n1. Generate opaque stable IDs rather than IDs derived directly from names or email addresses.\n2. Keep global actor identity stable across repositories and branch changes unless manually rotated.\n3. Keep `replica_id` stable for one installation/worktree writer, but allow explicit rotation and document whether clones receive a new replica.\n4. New worktrees should receive distinct replica IDs when they can write independently.\n5. Session IDs must be unique and non-reused.\n6. Agent IDs must distinguish separate agents/models where attribution matters.\n7. Identity aliases and provider links may change without rewriting historical events.\n\n## ESDB integration\n\nEvery canonical ESDB event introduced by #336 must include resolved identity provenance:\n\n- actor ID and display label at event time;\n- executing agent ID and model/provider metadata where applicable;\n- delegation relationship;\n- replica and session IDs;\n- resolution source and verification state;\n- optional provider-account references;\n- no unnecessary private fields.\n\nHistorical records must retain their original attribution even after a user changes their current display name or linked account.\n\n## Trust and privacy\n\n- Provider auto-detection establishes evidence, not absolute identity proof.\n- Organization policy may require a configured mapping, signed attestation, or verified account ID for privileged actions.\n- Do not expose email by default in committed canonical events.\n- Do not store provider tokens or credentials in Specsmith config or ESDB.\n- A user may disable provider detection or particular detectors.\n- Manual override must be visible in provenance.\n- Shared machines must support multiple named identity profiles without overwriting each other.\n\n## Named tests and binary pass/fail conditions\n\n### IDENTITY-001 — GitHub detection\n\n**Pass:** with a mocked/current GitHub CLI account, Specsmith links the account as provider evidence, creates or selects a stable actor profile, and records the detection source.\n\n**Fail:** the login string alone becomes the canonical ID or credentials are persisted.\n\n### IDENTITY-002 — Offline fallback\n\n**Pass:** without network/provider CLIs, configured global identity remains usable; otherwise Git/OS fallback is marked low-confidence with actionable guidance.\n\n**Fail:** normal commands fail solely because provider detection is unavailable.\n\n### IDENTITY-003 — Precedence\n\n**Pass:** explicit > environment > local > project policy/mapping > global > detected provider > Git > OS, with `identity explain` showing each candidate and winner.\n\n**Fail:** a lower layer silently replaces a higher configured identity.\n\n### IDENTITY-004 — Same display name, different users\n\n**Pass:** two profiles with the same display name retain different actor IDs and remain distinguishable after ESDB merge.\n\n**Fail:** profiles collapse because names match.\n\n### IDENTITY-005 — One user, multiple replicas\n\n**Pass:** one actor working in two independent worktrees has one actor ID and two distinct replica IDs; merged events retain both.\n\n**Fail:** replicas are conflated or actor identity changes by worktree.\n\n### IDENTITY-006 — Multiple agents for one user\n\n**Pass:** two agents acting for one human share the delegated actor ID but have distinct agent IDs and session IDs.\n\n**Fail:** agent actions cannot be attributed separately or appear as direct human actions without delegation.\n\n### IDENTITY-007 — Manual override\n\n**Pass:** a user can select a different local/global profile, provenance records the manual source, and historical events remain unchanged.\n\n**Fail:** changing identity rewrites history or silently affects another worktree.\n\n### IDENTITY-008 — Provider account change\n\n**Pass:** linking a new provider account updates the current identity profile without changing actor ID unless the user explicitly creates/selects another actor.\n\n**Fail:** provider username changes create accidental new identities or merge unrelated users.\n\n### IDENTITY-009 — Replica rotation\n\n**Pass:** explicit rotation creates a new replica ID with a recorded predecessor link; old events remain attributable.\n\n**Fail:** rotation rewrites old events or reuses the previous ID.\n\n### IDENTITY-010 — Shared machine profiles\n\n**Pass:** multiple named profiles coexist globally and project-local selection chooses one without modifying the others.\n\n**Fail:** detecting or selecting one user overwrites another user's profile.\n\n### IDENTITY-011 — Privacy\n\n**Pass:** email and private provider metadata are omitted/redacted by default from committed events and normal output.\n\n**Fail:** private fields appear without explicit policy opt-in.\n\n### IDENTITY-012 — Unauthorized claim\n\n**Pass:** an event or environment override claiming another configured actor without required mapping/attestation is marked unverified or blocked according to project policy.\n\n**Fail:** a matching string is treated as verified identity.\n\n### IDENTITY-013 — Cross-platform stability\n\n**Pass:** Linux, Windows, and macOS resolve the same configured actor profile semantics while maintaining platform-local replica identity.\n\n**Fail:** path, case, hostname, or username differences change actor identity unexpectedly.\n\n### IDENTITY-014 — ESDB merge attribution\n\n**Pass:** multi-user events merged under #336 retain actor, agent, replica, session, delegation, and verification fields with deterministic materialized results.\n\n**Fail:** attribution is dropped, overwritten, or changed by merge order.\n\n## Acceptance criteria\n\n- [ ] Centralized identity resolver exists and uses #339 configuration precedence.\n- [ ] Actor, agent, replica, and session identities are distinct.\n- [ ] GitHub and other provider detection is pluggable, read-only, optional, and explainable.\n- [ ] Global defaults and local overrides are supported.\n- [ ] Users can manually create, select, modify, link, and inspect identities.\n- [ ] ESDB events retain stable multi-user/multi-agent attribution.\n- [ ] Private data and credentials are not written by default.\n- [ ] IDENTITY-001 through IDENTITY-014 exist and pass with #337 machine-readable evidence.\n\n## Non-goals\n\n- Do not make GitHub mandatory for Specsmith identity.\n- Do not claim provider detection proves legal identity.\n- Do not use a mutable display name as a primary key.\n- Do not store authentication tokens.\n- Do not put personal local identity values into tracked project configuration by default.\n\n## Agent execution notes\n\nImplement #339's config resolver first. Keep identity detection adapters pure and independently testable. Reuse the resolved identity object everywhere instead of adding new environment lookups in individual subsystems. Coordinate the event envelope and multi-user tests with #336.",
"closed_by": null,
"reactions": {
"url": "https://api.github.com/repos/layer1labs/specsmith/issues/338/reactions",
"total_count": 0,
"+1": 0,
"-1": 0,
"laugh": 0,
"hooray": 0,
"confused": 0,
"heart": 0,
"rocket": 0,
"eyes": 0
},
"timeline_url": "https://api.github.com/repos/layer1labs/specsmith/issues/338/timeline",
"performed_via_github_app": {
"id": 1144995,
"client_id": "Iv23liVemv8A9if9v0F2",
"slug": "chatgpt-codex-connector",
"node_id": "A_kwHOAOQ6Gs4AEXij",
"owner": {
"login": "openai",
"id": 14957082,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjE0OTU3MDgy",
"avatar_url": "https://avatars.githubusercontent.com/u/14957082?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/openai",
"html_url": "https://github.com/openai",
"followers_url": "https://api.github.com/users/openai/followers",
"following_url": "https://api.github.com/users/openai/following{/other_user}",
"gists_url": "https://api.github.com/users/openai/gists{/gist_id}",
"starred_url": "https://api.github.com/users/openai/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/openai/subscriptions",
"organizations_url": "https://api.github.com/users/openai/orgs",
"repos_url": "https://api.github.com/users/openai/repos",
"events_url": "https://api.github.com/users/openai/events{/privacy}",
"received_events_url": "https://api.github.com/users/openai/received_events",
"type": "Organization",
"user_view_type": "public",
"site_admin": false
},
"name": "ChatGPT Codex Connector",
"description": "Bring ChatGPT and Codex to your GitHub repositories.",
"external_url": "https://www.chatgpt.com",
"html_url": "https://github.com/apps/chatgpt-codex-connector",
"created_at": "2025-02-14T01:37:05Z",
"updated_at": "2026-04-20T16:37:15Z",
"permissions": {
"actions": "write",
"checks": "read",
"contents": "write",
"emails": "read",
"issues": "write",
"metadata": "read",
"pull_requests": "write",
"statuses": "read",
"workflows": "write"
},
"events": [
"check_run",
"check_suite",
"commit_comment",
"issues",
"issue_comment",
"pull_request",
"pull_request_review",
"pull_request_review_comment",
"pull_request_review_thread",
"repository",
"status",
"sub_issues"
]
},
"state_reason": null,
"pinned_comment": null
},
{
"url": "https://api.github.com/repos/layer1labs/specsmith/issues/337",
"repository_url": "https://api.github.com/repos/layer1labs/specsmith",
"labels_url": "https://api.github.com/repos/layer1labs/specsmith/issues/337/labels{/name}",
"comments_url": "https://api.github.com/repos/layer1labs/specsmith/issues/337/comments",
"events_url": "https://api.github.com/repos/layer1labs/specsmith/issues/337/events",
"html_url": "https://github.com/layer1labs/specsmith/issues/337",
"id": 4904837706,
"node_id": "I_kwDOR2RC5c8AAAABJFniSg",
"number": 337,
"title": "Require traceable test cases and binary pass/fail evidence for the release and context epics",
"user": {
"login": "tbitcs",
"id": 98970594,
"node_id": "U_kgDOBeYr4g",
"avatar_url": "https://avatars.githubusercontent.com/u/98970594?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/tbitcs",
"html_url": "https://github.com/tbitcs",
"followers_url": "https://api.github.com/users/tbitcs/followers",
"following_url": "https://api.github.com/users/tbitcs/following{/other_user}",
"gists_url": "https://api.github.com/users/tbitcs/gists{/gist_id}",
"starred_url": "https://api.github.com/users/tbitcs/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/tbitcs/subscriptions",
"organizations_url": "https://api.github.com/users/tbitcs/orgs",
"repos_url": "https://api.github.com/users/tbitcs/repos",
"events_url": "https://api.github.com/users/tbitcs/events{/privacy}",
"received_events_url": "https://api.github.com/users/tbitcs/received_events",
"type": "User",
"user_view_type": "public",
"site_admin": false
},
"labels": [
],
"state": "open",
"locked": false,
"assignees": [
],
"milestone": null,
"comments": 1,
"created_at": "2026-07-16T18:20:14Z",
"updated_at": "2026-07-16T19:05:32Z",
"closed_at": null,
"assignee": null,
"author_association": "CONTRIBUTOR",
"issue_field_values": [
],
"type": null,
"active_lock_reason": null,
"sub_issues_summary": {
"total": 0,
"completed": 0,
"percent_completed": 0
},
"issue_dependencies_summary": {