llm-wb 0.1.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. package/.agentic/00.chat/README.md +78 -0
  2. package/.agentic/00.chat/checklists/before-commit.md +195 -0
  3. package/.agentic/00.chat/checklists/llm-workbench-public-beta.md +94 -0
  4. package/.agentic/00.chat/commands/README.md +108 -0
  5. package/.agentic/00.chat/migration-plan.md +132 -0
  6. package/.agentic/00.chat/skills/session-summary.md +48 -0
  7. package/.agentic/00.chat/standards/llm-workbench-public-beta-contract.md +216 -0
  8. package/.agentic/00.chat/standards/main-refresh-conflict-types.md +358 -0
  9. package/.agentic/00.chat/workflows/README.md +40 -0
  10. package/.agentic/00.chat/workflows/bootstrap-chat-workbench-repo.md +212 -0
  11. package/.agentic/00.chat/workflows/chat-cleanup.md +102 -0
  12. package/.agentic/00.chat/workflows/chat-commit.md +56 -0
  13. package/.agentic/00.chat/workflows/chat-promote-to-main.md +169 -0
  14. package/.agentic/00.chat/workflows/chat-refresh-from-main.md +242 -0
  15. package/.agentic/00.chat/workflows/chat-reporting.md +69 -0
  16. package/.agentic/00.chat/workflows/chat-start.md +173 -0
  17. package/.agentic/00.chat/workflows/chat-upstream-reusable-lesson.md +123 -0
  18. package/.agentic/shared/standards/README.md +32 -0
  19. package/.agentic/shared/standards/upstream-repo-bootstrap.md +131 -0
  20. package/.agentic/shared/workflows/README.md +35 -0
  21. package/.agentic/shared/workflows/capability-resolution-workflow.md +189 -0
  22. package/.agentic/shared/workflows/change-shared-process.md +92 -0
  23. package/.cursor/rules/llm-workbench.mdc +17 -0
  24. package/.github/copilot-instructions.md +16 -0
  25. package/AGENTS.md +63 -0
  26. package/CLAUDE.md +16 -0
  27. package/CONTRIBUTING.md +57 -0
  28. package/LICENSE +21 -0
  29. package/LLM_WORKBENCH.md +17 -0
  30. package/README.md +98 -0
  31. package/SECURITY.md +44 -0
  32. package/bin/llm-workbench.js +672 -0
  33. package/docs/00.chat/README.md +47 -0
  34. package/docs/00.chat/llm-workbench-acceptance-matrix.md +55 -0
  35. package/docs/00.chat/script-layout.md +107 -0
  36. package/docs/adapting-to-your-repo.md +29 -0
  37. package/docs/concepts.md +38 -0
  38. package/docs/install.md +114 -0
  39. package/docs/public-beta-contract.md +45 -0
  40. package/docs/workflows.md +103 -0
  41. package/examples/minimal-repo/README.md +13 -0
  42. package/package.json +93 -0
  43. package/scripts/00.chat/README.md +46 -0
  44. package/scripts/00.chat/bootstrap/README.md +35 -0
  45. package/scripts/00.chat/bootstrap/audit-chat-bootstrap-file-set/README.md +39 -0
  46. package/scripts/00.chat/bootstrap/audit-chat-bootstrap-file-set/script.sh +213 -0
  47. package/scripts/00.chat/closeout/README.md +30 -0
  48. package/scripts/00.chat/closeout/build-closeout-prompt/README.md +35 -0
  49. package/scripts/00.chat/closeout/build-closeout-prompt/script.sh +124 -0
  50. package/scripts/00.chat/command/README.md +31 -0
  51. package/scripts/00.chat/command/close/README.md +30 -0
  52. package/scripts/00.chat/command/close/script.sh +25 -0
  53. package/scripts/00.chat/command/dispatcher/README.md +46 -0
  54. package/scripts/00.chat/command/dispatcher/script.sh +91 -0
  55. package/scripts/00.chat/command/dispatcher/smoke-test.sh +168 -0
  56. package/scripts/00.chat/command/new/README.md +32 -0
  57. package/scripts/00.chat/command/new/script.sh +28 -0
  58. package/scripts/00.chat/command/open-window/README.md +38 -0
  59. package/scripts/00.chat/command/open-window/script.sh +25 -0
  60. package/scripts/00.chat/command/package-scripts/README.md +34 -0
  61. package/scripts/00.chat/command/package-scripts/smoke-test.sh +113 -0
  62. package/scripts/00.chat/git/README.md +30 -0
  63. package/scripts/00.chat/git/cleanup-empty-chat-branches/README.md +36 -0
  64. package/scripts/00.chat/git/cleanup-empty-chat-branches/script.sh +243 -0
  65. package/scripts/00.chat/git/cleanup-empty-chat-branches/smoke-test.sh +136 -0
  66. package/scripts/00.chat/local-merge/README.md +30 -0
  67. package/scripts/00.chat/local-merge/list-active-chat-branches/README.md +29 -0
  68. package/scripts/00.chat/local-merge/list-active-chat-branches/script.sh +109 -0
  69. package/scripts/00.chat/local-merge/report-chat-branch-overlaps/README.md +29 -0
  70. package/scripts/00.chat/local-merge/report-chat-branch-overlaps/script.sh +142 -0
  71. package/scripts/00.chat/local-merge/verify-chat-ready-to-merge-local-main/README.md +33 -0
  72. package/scripts/00.chat/local-merge/verify-chat-ready-to-merge-local-main/script.sh +345 -0
  73. package/scripts/00.chat/local-merge/verify-chat-ready-to-merge-local-main/smoke-test.sh +244 -0
  74. package/scripts/00.chat/main-refresh/README.md +39 -0
  75. package/scripts/00.chat/main-refresh/apply-rehearsed-refresh/README.md +32 -0
  76. package/scripts/00.chat/main-refresh/apply-rehearsed-refresh/script.sh +198 -0
  77. package/scripts/00.chat/main-refresh/check-chat-is-current-with-main/README.md +30 -0
  78. package/scripts/00.chat/main-refresh/check-chat-is-current-with-main/script.sh +121 -0
  79. package/scripts/00.chat/main-refresh/classify-conflict/README.md +39 -0
  80. package/scripts/00.chat/main-refresh/classify-conflict/script.sh +169 -0
  81. package/scripts/00.chat/main-refresh/classify-conflict/smoke-test.sh +137 -0
  82. package/scripts/00.chat/main-refresh/classify-refresh-readiness/README.md +35 -0
  83. package/scripts/00.chat/main-refresh/classify-refresh-readiness/script.sh +171 -0
  84. package/scripts/00.chat/main-refresh/classify-refresh-readiness/smoke-test.sh +132 -0
  85. package/scripts/00.chat/main-refresh/rehearse-refresh-from-main/README.md +34 -0
  86. package/scripts/00.chat/main-refresh/rehearse-refresh-from-main/script.sh +124 -0
  87. package/scripts/00.chat/main-refresh/rehearse-refresh-from-main/smoke-test.sh +257 -0
  88. package/scripts/00.chat/main-refresh/show-main-update-status/README.md +31 -0
  89. package/scripts/00.chat/main-refresh/show-main-update-status/script.sh +73 -0
  90. package/scripts/00.chat/main-refresh/verify-conflict-audit/README.md +37 -0
  91. package/scripts/00.chat/main-refresh/verify-conflict-audit/script.sh +154 -0
  92. package/scripts/00.chat/main-refresh/verify-conflict-audit/smoke-test.sh +99 -0
  93. package/scripts/00.chat/metrics/README.md +35 -0
  94. package/scripts/00.chat/metrics/data/chat-pricing.json +107 -0
  95. package/scripts/00.chat/metrics/data/chat-pricing.schema.json +63 -0
  96. package/scripts/00.chat/metrics/estimate-chat-cost/README.md +40 -0
  97. package/scripts/00.chat/metrics/estimate-chat-cost/script.js +130 -0
  98. package/scripts/00.chat/migration/README.md +30 -0
  99. package/scripts/00.chat/migration/audit-chat-layer-migration/README.md +33 -0
  100. package/scripts/00.chat/migration/audit-chat-layer-migration/script.sh +127 -0
  101. package/scripts/00.chat/recovery/README.md +30 -0
  102. package/scripts/00.chat/recovery/import-active-paths-to-chat-worktree/README.md +76 -0
  103. package/scripts/00.chat/recovery/import-active-paths-to-chat-worktree/script.sh +212 -0
  104. package/scripts/00.chat/recovery/import-active-paths-to-chat-worktree/smoke-test.sh +162 -0
  105. package/scripts/00.chat/reporting/README.md +30 -0
  106. package/scripts/00.chat/reporting/generate-commit-log-summary/README.md +35 -0
  107. package/scripts/00.chat/reporting/generate-commit-log-summary/script.sh +299 -0
  108. package/scripts/00.chat/reporting/generate-commit-log-summary/smoke-test.sh +93 -0
  109. package/scripts/00.chat/reporting/report-chat-workspaces/README.md +32 -0
  110. package/scripts/00.chat/reporting/report-chat-workspaces/script.sh +82 -0
  111. package/scripts/00.chat/session-log/README.md +33 -0
  112. package/scripts/00.chat/session-log/check-commit-prerequisites/README.md +89 -0
  113. package/scripts/00.chat/session-log/check-commit-prerequisites/script.sh +121 -0
  114. package/scripts/00.chat/session-log/check-commit-prerequisites/smoke-test.sh +119 -0
  115. package/scripts/00.chat/session-log/check-commitlog-deletions/README.md +90 -0
  116. package/scripts/00.chat/session-log/check-commitlog-deletions/script.sh +131 -0
  117. package/scripts/00.chat/session-log/check-commitlog-deletions/smoke-test.sh +123 -0
  118. package/scripts/00.chat/session-log/checkpoint-chat-session-log/README.md +98 -0
  119. package/scripts/00.chat/session-log/checkpoint-chat-session-log/script.sh +126 -0
  120. package/scripts/00.chat/session-log/paths/README.md +38 -0
  121. package/scripts/00.chat/session-log/paths/lib.sh +133 -0
  122. package/scripts/00.chat/session-log/prepare-chat-session-before-commit/README.md +90 -0
  123. package/scripts/00.chat/session-log/prepare-chat-session-before-commit/script.sh +145 -0
  124. package/scripts/00.chat/session-log/read-current-chat-log/README.md +44 -0
  125. package/scripts/00.chat/session-log/read-current-chat-log/script.sh +92 -0
  126. package/scripts/00.chat/session-log/read-current-chat-log/smoke-test.sh +127 -0
  127. package/scripts/00.chat/session-log/record-chat-commit/README.md +133 -0
  128. package/scripts/00.chat/session-log/record-chat-commit/script.sh +394 -0
  129. package/scripts/00.chat/session-log/record-chat-commit/smoke-test.sh +227 -0
  130. package/scripts/00.chat/session-log/record-main-refresh-conflict/README.md +34 -0
  131. package/scripts/00.chat/session-log/record-main-refresh-conflict/script.sh +239 -0
  132. package/scripts/00.chat/session-log/rename-current-chat-log-folder/README.md +32 -0
  133. package/scripts/00.chat/session-log/rename-current-chat-log-folder/script.sh +112 -0
  134. package/scripts/00.chat/session-log/update-chat-log/README.md +32 -0
  135. package/scripts/00.chat/session-log/update-chat-log/script.sh +294 -0
  136. package/scripts/00.chat/startup/README.md +37 -0
  137. package/scripts/00.chat/startup/auto-start-missing-session/README.md +113 -0
  138. package/scripts/00.chat/startup/auto-start-missing-session/script.sh +54 -0
  139. package/scripts/00.chat/startup/resolve-current-chat-session/README.md +57 -0
  140. package/scripts/00.chat/startup/resolve-current-chat-session/script.sh +47 -0
  141. package/scripts/00.chat/startup/resolve-current-chat-session/smoke-test.sh +130 -0
  142. package/scripts/00.chat/startup/start-chat-session/README.md +197 -0
  143. package/scripts/00.chat/startup/start-chat-session/script.sh +330 -0
  144. package/scripts/00.chat/startup/start-chat-session/smoke-test.sh +182 -0
  145. package/scripts/00.chat/startup/start-new-chat/README.md +31 -0
  146. package/scripts/00.chat/startup/start-new-chat/script.sh +29 -0
  147. package/scripts/00.chat/transcript/README.md +36 -0
  148. package/scripts/00.chat/transcript/discover-codex-session-log/README.md +32 -0
  149. package/scripts/00.chat/transcript/discover-codex-session-log/script.sh +106 -0
  150. package/scripts/00.chat/transcript/register-codex-session-log/README.md +32 -0
  151. package/scripts/00.chat/transcript/register-codex-session-log/script.sh +115 -0
  152. package/scripts/00.chat/worktree/README.md +32 -0
  153. package/scripts/00.chat/worktree/check-write-location/README.md +87 -0
  154. package/scripts/00.chat/worktree/check-write-location/script.sh +95 -0
  155. package/scripts/00.chat/worktree/dirty-worktree-check/README.md +77 -0
  156. package/scripts/00.chat/worktree/dirty-worktree-check/script.sh +93 -0
  157. package/scripts/00.chat/worktree/ensure-chat-worktree/README.md +33 -0
  158. package/scripts/00.chat/worktree/ensure-chat-worktree/script.sh +132 -0
  159. package/scripts/00.chat/worktree/open-window/README.md +34 -0
  160. package/scripts/00.chat/worktree/open-window/script.sh +131 -0
  161. package/scripts/00.chat/worktree/paths/README.md +32 -0
  162. package/scripts/00.chat/worktree/paths/lib.sh +71 -0
  163. package/scripts/01.harness/artifact-metadata/check-headers/script.sh +522 -0
  164. package/scripts/01.harness/artifact-metadata/check-headers/smoke-test.sh +48 -0
  165. package/scripts/01.harness/check-deterministic-process-drift.sh +416 -0
  166. package/scripts/01.harness/check-governed-script-command-drift.sh +184 -0
  167. package/scripts/01.harness/run-governed-script.sh +178 -0
  168. package/scripts/install.sh +503 -0
  169. package/scripts/uninstall.sh +199 -0
  170. package/tests/smoke-test-install.sh +70 -0
@@ -0,0 +1,39 @@
1
+ <!-- agentic-artifact:
2
+ schema: agentic-artifact/v2
3
+ id: chat.script.main-refresh.classify-conflict.readme
4
+ version: 1
5
+ status: active
6
+ layer: 00.chat
7
+ domain: main-refresh
8
+ disciplines:
9
+ - agentic
10
+ kind: capability-readme
11
+ purpose: Explain deterministic main-refresh conflict classification.
12
+ portability:
13
+ class: required
14
+ targets:
15
+ - llm-workbench
16
+ used_by:
17
+ - id: chat.script.main-refresh.classify-conflict
18
+ path: scripts/00.chat/main-refresh/classify-conflict/script.sh
19
+ - id: chat.standards.main-refresh-conflict-types
20
+ path: .agentic/00.chat/standards/main-refresh-conflict-types.md
21
+ -->
22
+ # Classify Main Refresh Conflict
23
+
24
+ `script.sh` classifies one conflicted path using the governed conflict types in
25
+ `.agentic/00.chat/standards/main-refresh-conflict-types.md`.
26
+
27
+ The classifier is intentionally conservative. It recognizes deterministic
28
+ patterns that have already appeared in main-refresh recovery evidence, including
29
+ ownership migration, retired generated commit-log artifacts, retired artifact
30
+ policy scripts, session bookkeeping, and add/add script conflicts. If no known
31
+ type fits, it reports `normal-repo-conflict` for authored content or
32
+ `unsupported-conflict` when the shape is ambiguous.
33
+
34
+ Run it from a preflight or chat worktree that still has Git conflict stages for
35
+ the path:
36
+
37
+ ```bash
38
+ bash scripts/00.chat/main-refresh/classify-conflict/script.sh <path>
39
+ ```
@@ -0,0 +1,169 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ # agentic-artifact:
5
+ # schema: agentic-artifact/v2
6
+ # id: chat.script.main-refresh.classify-conflict
7
+ # version: 1
8
+ # status: active
9
+ # layer: 00.chat
10
+ # domain: main-refresh
11
+ # disciplines:
12
+ # - agentic
13
+ # kind: script
14
+ # purpose: Classify one main-refresh conflict path using governed conflict types.
15
+ # portability:
16
+ # class: required
17
+ # targets:
18
+ # - llm-workbench
19
+ # used_by:
20
+ # - id: chat.workflows.chat-refresh-from-main
21
+ # path: .agentic/00.chat/workflows/chat-refresh-from-main.md
22
+ # - id: chat.standards.main-refresh-conflict-types
23
+ # path: .agentic/00.chat/standards/main-refresh-conflict-types.md
24
+ # effects:
25
+ # - read-only
26
+
27
+ usage() {
28
+ cat <<'EOF'
29
+ Usage:
30
+ script.sh <conflicted-path>
31
+
32
+ Classifies one conflicted path from the Git index and prints:
33
+ path=<path>
34
+ type=<conflict-type>
35
+ reason=<classification-reason>
36
+
37
+ The path must have unresolved Git conflict stages.
38
+ EOF
39
+ }
40
+
41
+ if [ $# -ne 1 ]; then
42
+ usage >&2
43
+ exit 2
44
+ fi
45
+
46
+ CONFLICT_PATH="$1"
47
+
48
+ if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
49
+ echo "ERROR: not inside a Git worktree." >&2
50
+ exit 1
51
+ fi
52
+
53
+ STAGES="$(git ls-files -u -- "$CONFLICT_PATH")"
54
+
55
+ if [ -z "$STAGES" ]; then
56
+ echo "ERROR: path has no unresolved conflict stages: ${CONFLICT_PATH}" >&2
57
+ exit 1
58
+ fi
59
+
60
+ has_stage() {
61
+ local stage="$1"
62
+
63
+ printf '%s\n' "$STAGES" | awk -v stage="$stage" '$3 == stage { found = 1 } END { exit found ? 0 : 1 }'
64
+ }
65
+
66
+ stage_content() {
67
+ local stage="$1"
68
+
69
+ if has_stage "$stage"; then
70
+ git show ":${stage}:${CONFLICT_PATH}" 2>/dev/null || true
71
+ fi
72
+ }
73
+
74
+ BASE_PRESENT=0
75
+ OURS_PRESENT=0
76
+ THEIRS_PRESENT=0
77
+
78
+ if has_stage 1; then BASE_PRESENT=1; fi
79
+ if has_stage 2; then OURS_PRESENT=1; fi
80
+ if has_stage 3; then THEIRS_PRESENT=1; fi
81
+
82
+ BASE_CONTENT="$(stage_content 1)"
83
+ OURS_CONTENT="$(stage_content 2)"
84
+ THEIRS_CONTENT="$(stage_content 3)"
85
+ ALL_CONTENT="$BASE_CONTENT
86
+ $OURS_CONTENT
87
+ $THEIRS_CONTENT"
88
+
89
+ contains_any() {
90
+ local text="$1"
91
+ shift
92
+ local pattern
93
+
94
+ for pattern in "$@"; do
95
+ if printf '%s\n' "$text" | grep -Eq "$pattern"; then
96
+ return 0
97
+ fi
98
+ done
99
+
100
+ return 1
101
+ }
102
+
103
+ emit() {
104
+ local type="$1"
105
+ local reason="$2"
106
+
107
+ printf 'path=%s\n' "$CONFLICT_PATH"
108
+ printf 'type=%s\n' "$type"
109
+ printf 'reason=%s\n' "$reason"
110
+ }
111
+
112
+ case "$CONFLICT_PATH" in
113
+ commitLogs/README.md)
114
+ if [ "$OURS_PRESENT" = "0" ] || [ "$THEIRS_PRESENT" = "0" ]; then
115
+ emit "retired-artifact-delete-modify-conflict" "tracked aggregate commit log summary was deleted on one side and modified on the other"
116
+ exit 0
117
+ fi
118
+ emit "generated-artifact-conflict" "tracked aggregate commit log summary is a retired generated artifact"
119
+ exit 0
120
+ ;;
121
+ commitLogs/*/README.md)
122
+ emit "session-bookkeeping-conflict" "path is a chat session log; preserve recorded session evidence"
123
+ exit 0
124
+ ;;
125
+ esac
126
+
127
+ LEGACY_SHARED_ROOT=".agentic/shared"
128
+ LEGACY_WORKFLOWS="${LEGACY_SHARED_ROOT}/workflows"
129
+ LEGACY_CHECKLISTS="${LEGACY_SHARED_ROOT}/checklists"
130
+
131
+ case "$CONFLICT_PATH" in
132
+ "$LEGACY_WORKFLOWS/local-convergence.md"|"$LEGACY_WORKFLOWS/main-updated.md"|"$LEGACY_WORKFLOWS/chat-start-interview.md"|"$LEGACY_CHECKLISTS/before-commit.md")
133
+ emit "ownership-migration-conflict" "path is a retired shared chat-lifecycle surface whose canonical owner is under .agentic/00.chat"
134
+ exit 0
135
+ ;;
136
+ esac
137
+
138
+ case "$CONFLICT_PATH" in
139
+ *generate-commit-log-summary*|*commit-log-summary*)
140
+ if contains_any "$ALL_CONTENT" 'commitLogs/README\.md|--write|--check|--print|--output'; then
141
+ emit "retired-artifact-generator-conflict" "generator behavior touches retired tracked commitLogs/README.md summary policy"
142
+ exit 0
143
+ fi
144
+ ;;
145
+ *classify-main-refresh-dirty-state*|*classify-refresh-readiness*|*dirty-classifier*)
146
+ if contains_any "$ALL_CONTENT" 'commitLogs/README\.md|generated-commitlog-summary|generated.*summary'; then
147
+ emit "retired-artifact-policy-script-conflict" "classifier or test behavior treats retired commitLogs/README.md as active state"
148
+ exit 0
149
+ fi
150
+ ;;
151
+ esac
152
+
153
+ if [ "$BASE_PRESENT" = "0" ] && [ "$OURS_PRESENT" = "1" ] && [ "$THEIRS_PRESENT" = "1" ]; then
154
+ case "$CONFLICT_PATH" in
155
+ scripts/*|*.sh|*.js|*.mjs)
156
+ emit "script-add-add-conflict" "both sides added the same script-like path independently"
157
+ exit 0
158
+ ;;
159
+ esac
160
+ fi
161
+
162
+ case "$CONFLICT_PATH" in
163
+ .agentic/*|docs/*|scripts/*|src/*|tests/*|package.json)
164
+ emit "normal-repo-conflict" "authored repository content has no more specific governed conflict type"
165
+ ;;
166
+ *)
167
+ emit "unsupported-conflict" "path ownership or conflict shape is not covered by a deterministic classifier rule"
168
+ ;;
169
+ esac
@@ -0,0 +1,137 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ # agentic-artifact:
5
+ # schema: agentic-artifact/v2
6
+ # id: chat.script.main-refresh.classify-conflict.smoke-test
7
+ # version: 1
8
+ # status: active
9
+ # layer: 00.chat
10
+ # domain: main-refresh
11
+ # disciplines:
12
+ # - agentic
13
+ # kind: script
14
+ # purpose: Smoke test deterministic main-refresh conflict classification.
15
+ # portability:
16
+ # class: required
17
+ # targets:
18
+ # - llm-workbench
19
+ # used_by:
20
+ # - id: chat.script.main-refresh.classify-conflict
21
+ # path: scripts/00.chat/main-refresh/classify-conflict/script.sh
22
+ # effects:
23
+ # - writes-files
24
+
25
+ fail() {
26
+ echo "FAIL: $*" >&2
27
+ exit 1
28
+ }
29
+
30
+ SOURCE_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../.." && pwd -P)"
31
+ TMP_ROOT="$(mktemp -d "${TMPDIR:-/tmp}/classify-main-refresh-conflict-smoke.XXXXXX")"
32
+
33
+ cleanup() {
34
+ rm -rf "$TMP_ROOT"
35
+ }
36
+
37
+ trap cleanup EXIT
38
+
39
+ REPO="$TMP_ROOT/repo"
40
+ mkdir -p "$REPO"
41
+ git -C "$REPO" init -q
42
+ git -C "$REPO" config user.email test@example.com
43
+ git -C "$REPO" config user.name "Test User"
44
+
45
+ mkdir -p "$REPO/scripts/00.chat/main-refresh/classify-conflict"
46
+ cp "$SOURCE_ROOT/scripts/00.chat/main-refresh/classify-conflict/script.sh" "$REPO/scripts/00.chat/main-refresh/classify-conflict/script.sh"
47
+
48
+ cat > "$REPO/README.md" <<'EOF'
49
+ base
50
+ EOF
51
+ git -C "$REPO" add README.md scripts/00.chat/main-refresh/classify-conflict/script.sh
52
+ git -C "$REPO" commit -q -m base
53
+ git -C "$REPO" branch -M main
54
+
55
+ LEGACY_SHARED_ROOT=".agentic/shared"
56
+ LEGACY_WORKFLOWS="${LEGACY_SHARED_ROOT}/workflows"
57
+ LEGACY_MAIN_UPDATED="${LEGACY_WORKFLOWS}/main-updated.md"
58
+ LEGACY_SCRIPT_ROOT="scripts/shared"
59
+ LEGACY_CHAT_SCRIPTS="${LEGACY_SCRIPT_ROOT}/chat"
60
+ LEGACY_GENERATOR="${LEGACY_CHAT_SCRIPTS}/generate-commit-log-summary.sh"
61
+
62
+ git -C "$REPO" checkout -q -b chat/test
63
+ mkdir -p "$REPO/$LEGACY_WORKFLOWS"
64
+ cat > "$REPO/$LEGACY_MAIN_UPDATED" <<'EOF'
65
+ Compatibility pointer.
66
+ EOF
67
+ git -C "$REPO" add "$LEGACY_MAIN_UPDATED"
68
+ git -C "$REPO" commit -q -m "chat migration pointer"
69
+
70
+ git -C "$REPO" checkout -q main
71
+ mkdir -p "$REPO/$LEGACY_WORKFLOWS"
72
+ cat > "$REPO/$LEGACY_MAIN_UPDATED" <<'EOF'
73
+ Legacy workflow with preflight cleanup guidance.
74
+ EOF
75
+ git -C "$REPO" add "$LEGACY_MAIN_UPDATED"
76
+ git -C "$REPO" commit -q -m "main legacy workflow"
77
+
78
+ git -C "$REPO" checkout -q chat/test
79
+ set +e
80
+ git -C "$REPO" merge main >/dev/null 2>&1
81
+ MERGE_STATUS="$?"
82
+ set -e
83
+
84
+ if [ "$MERGE_STATUS" -eq 0 ]; then
85
+ fail "expected add/add conflict"
86
+ fi
87
+
88
+ OUTPUT="$(
89
+ cd "$REPO"
90
+ bash scripts/00.chat/main-refresh/classify-conflict/script.sh "$LEGACY_MAIN_UPDATED"
91
+ )"
92
+
93
+ if ! printf '%s\n' "$OUTPUT" | grep -q '^type=ownership-migration-conflict$'; then
94
+ fail "ownership migration conflict was not classified"
95
+ fi
96
+
97
+ git -C "$REPO" merge --abort
98
+ git -C "$REPO" checkout -q main
99
+
100
+ mkdir -p "$REPO/$LEGACY_CHAT_SCRIPTS"
101
+ cat > "$REPO/$LEGACY_GENERATOR" <<'EOF'
102
+ #!/usr/bin/env bash
103
+ echo "write commitLogs/README.md"
104
+ EOF
105
+ chmod +x "$REPO/$LEGACY_GENERATOR"
106
+ git -C "$REPO" add "$LEGACY_GENERATOR"
107
+ git -C "$REPO" commit -q -m "main generator"
108
+
109
+ git -C "$REPO" checkout -q chat/test
110
+ mkdir -p "$REPO/$LEGACY_CHAT_SCRIPTS"
111
+ cat > "$REPO/$LEGACY_GENERATOR" <<'EOF'
112
+ #!/usr/bin/env bash
113
+ echo "print only"
114
+ EOF
115
+ chmod +x "$REPO/$LEGACY_GENERATOR"
116
+ git -C "$REPO" add "$LEGACY_GENERATOR"
117
+ git -C "$REPO" commit -q -m "chat generator"
118
+
119
+ set +e
120
+ git -C "$REPO" merge main >/dev/null 2>&1
121
+ MERGE_STATUS="$?"
122
+ set -e
123
+
124
+ if [ "$MERGE_STATUS" -eq 0 ]; then
125
+ fail "expected generator add/add conflict"
126
+ fi
127
+
128
+ OUTPUT="$(
129
+ cd "$REPO"
130
+ bash scripts/00.chat/main-refresh/classify-conflict/script.sh "$LEGACY_GENERATOR"
131
+ )"
132
+
133
+ if ! printf '%s\n' "$OUTPUT" | grep -q '^type=retired-artifact-generator-conflict$'; then
134
+ fail "retired artifact generator conflict was not classified"
135
+ fi
136
+
137
+ echo "main refresh conflict classifier smoke test passed."
@@ -0,0 +1,35 @@
1
+ <!-- agentic-artifact:
2
+ schema: agentic-artifact/v2
3
+ id: chat.script.main-refresh.classify-refresh-readiness.readme
4
+ version: 1
5
+ status: active
6
+ layer: 00.chat
7
+ domain: main-refresh
8
+ disciplines:
9
+ - agentic
10
+ kind: guide
11
+ purpose: Explain dirty-state classification before refreshing a chat branch from main.
12
+ portability:
13
+ class: required
14
+ targets:
15
+ - llm-workbench
16
+ used_by:
17
+ - id: chat.script.main-refresh.classify-refresh-readiness
18
+ path: scripts/00.chat/main-refresh/classify-refresh-readiness/script.sh
19
+ - id: chat.script.main-refresh.classify-refresh-readiness.smoke-test
20
+ path: scripts/00.chat/main-refresh/classify-refresh-readiness/smoke-test.sh
21
+ -->
22
+ # Classify Refresh Readiness
23
+
24
+ This read-only capability answers: can this chat worktree refresh from `main`
25
+ right now?
26
+
27
+ It classifies the active worktree before any refresh action:
28
+
29
+ - `clean`: normal refresh or preflight can continue.
30
+ - `current-session-bookkeeping`: only the current session log is dirty.
31
+ - `repo-work`: normal repository files are dirty and need an approved commit or
32
+ recovery path before refresh.
33
+ - `unsupported-dirty`: the workflow does not yet own a safe recovery path.
34
+
35
+ The script reports state only. Workflows decide what action is allowed next.
@@ -0,0 +1,171 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ # agentic-artifact:
5
+ # schema: agentic-artifact/v2
6
+ # id: chat.script.main-refresh.classify-refresh-readiness
7
+ # version: 1
8
+ # status: active
9
+ # layer: 00.chat
10
+ # domain: main-refresh
11
+ # disciplines:
12
+ # - agentic
13
+ # kind: script
14
+ # purpose: Classify whether the current chat worktree is ready to refresh from main.
15
+ # portability:
16
+ # class: required
17
+ # targets:
18
+ # - llm-workbench
19
+ # used_by:
20
+ # - id: chat.workflows.chat-refresh-from-main
21
+ # path: .agentic/00.chat/workflows/chat-refresh-from-main.md
22
+ # - id: chat.script.main-refresh.rehearse-refresh-from-main
23
+ # path: scripts/00.chat/main-refresh/rehearse-refresh-from-main/script.sh
24
+ # effects:
25
+ # - read-only
26
+
27
+ usage() {
28
+ cat <<'EOF'
29
+ Usage:
30
+ script.sh [base-branch]
31
+
32
+ Classifies dirty worktree state before refreshing a chat branch from main.
33
+ The classifier reports state only; workflows decide what actions are allowed.
34
+ EOF
35
+ }
36
+
37
+ BASE_BRANCH="${1:-main}"
38
+
39
+ if [ $# -gt 1 ]; then
40
+ usage >&2
41
+ exit 2
42
+ fi
43
+
44
+ case "$BASE_BRANCH" in
45
+ -h|--help)
46
+ usage
47
+ exit 0
48
+ ;;
49
+ esac
50
+
51
+ if ! git show-ref --verify --quiet "refs/heads/${BASE_BRANCH}"; then
52
+ echo "classification=unsupported-dirty"
53
+ echo "recoverability=blocked"
54
+ echo "reason=base branch does not exist: ${BASE_BRANCH}"
55
+ exit 1
56
+ fi
57
+
58
+ # shellcheck source=../../session-log/paths/lib.sh
59
+ source "scripts/00.chat/session-log/paths/lib.sh"
60
+
61
+ BRANCH="$(git branch --show-current)"
62
+
63
+ if [ -z "$BRANCH" ]; then
64
+ echo "classification=unsupported-dirty"
65
+ echo "recoverability=blocked"
66
+ echo "reason=current HEAD is detached"
67
+ exit 1
68
+ fi
69
+
70
+ SESSION_ID=""
71
+ LOG_FILE=""
72
+
73
+ if SESSION_ID="$(chat_session_id_from_branch "$BRANCH")"; then
74
+ LOG_FILE="$(chat_log_file_for_session "$SESSION_ID")"
75
+ fi
76
+
77
+ STATUS_FILE="$(mktemp)"
78
+ DIRTY_FILE="$(mktemp)"
79
+ STAGED_FILE="$(mktemp)"
80
+ INCOMING_FILE="$(mktemp)"
81
+ OVERLAP_FILE="$(mktemp)"
82
+
83
+ cleanup() {
84
+ rm -f "$STATUS_FILE" "$DIRTY_FILE" "$STAGED_FILE" "$INCOMING_FILE" "$OVERLAP_FILE"
85
+ }
86
+
87
+ trap cleanup EXIT
88
+
89
+ git status --porcelain > "$STATUS_FILE"
90
+
91
+ if [ ! -s "$STATUS_FILE" ]; then
92
+ echo "classification=clean"
93
+ echo "recoverability=normal-refresh"
94
+ echo "reason=worktree is clean"
95
+ exit 0
96
+ fi
97
+
98
+ awk '{ print substr($0, 4) }' "$STATUS_FILE" | sort -u > "$DIRTY_FILE"
99
+ awk 'substr($0, 1, 1) != " " && substr($0, 1, 1) != "?" { print substr($0, 4) }' \
100
+ "$STATUS_FILE" | sort -u > "$STAGED_FILE"
101
+ git diff --name-only "HEAD...${BASE_BRANCH}" | sort -u > "$INCOMING_FILE"
102
+ comm -12 "$DIRTY_FILE" "$INCOMING_FILE" > "$OVERLAP_FILE"
103
+
104
+ emit_common() {
105
+ echo "branch=${BRANCH}"
106
+ echo "base_branch=${BASE_BRANCH}"
107
+ if [ -n "$SESSION_ID" ]; then
108
+ echo "session_id=${SESSION_ID}"
109
+ echo "session_log=${LOG_FILE}"
110
+ else
111
+ echo "session_id="
112
+ echo "session_log="
113
+ fi
114
+ echo "dirty_paths<<EOF"
115
+ cat "$DIRTY_FILE"
116
+ echo "EOF"
117
+ echo "staged_paths<<EOF"
118
+ cat "$STAGED_FILE"
119
+ echo "EOF"
120
+ echo "incoming_overlap_paths<<EOF"
121
+ cat "$OVERLAP_FILE"
122
+ echo "EOF"
123
+ }
124
+
125
+ only_allowed_paths="yes"
126
+ repo_work_paths=""
127
+ other_commitlog_paths=""
128
+
129
+ while IFS= read -r path; do
130
+ if [ -z "$path" ]; then
131
+ continue
132
+ fi
133
+
134
+ if [ -n "$LOG_FILE" ] && [ "$path" = "$LOG_FILE" ]; then
135
+ continue
136
+ fi
137
+
138
+ only_allowed_paths="no"
139
+
140
+ case "$path" in
141
+ commitLogs/*/README.md)
142
+ other_commitlog_paths="${other_commitlog_paths}${path}
143
+ "
144
+ ;;
145
+ *)
146
+ repo_work_paths="${repo_work_paths}${path}
147
+ "
148
+ ;;
149
+ esac
150
+ done < "$DIRTY_FILE"
151
+
152
+ if [ "$only_allowed_paths" = "yes" ]; then
153
+ echo "classification=current-session-bookkeeping"
154
+ echo "recoverability=checkpoint-or-preserve"
155
+ echo "reason=dirty paths are limited to the current session log"
156
+ emit_common
157
+ exit 0
158
+ fi
159
+
160
+ if [ -n "${repo_work_paths// }" ]; then
161
+ echo "classification=repo-work"
162
+ echo "recoverability=checkpoint-required"
163
+ echo "reason=dirty paths include normal repository work"
164
+ emit_common
165
+ exit 0
166
+ fi
167
+
168
+ echo "classification=unsupported-dirty"
169
+ echo "recoverability=blocked"
170
+ echo "reason=dirty paths are outside governed main-refresh recovery categories"
171
+ emit_common
@@ -0,0 +1,132 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ # agentic-artifact:
5
+ # schema: agentic-artifact/v2
6
+ # id: chat.script.main-refresh.classify-refresh-readiness.smoke-test
7
+ # version: 1
8
+ # status: active
9
+ # layer: 00.chat
10
+ # domain: main-refresh
11
+ # disciplines:
12
+ # - agentic
13
+ # kind: script
14
+ # purpose: Smoke test refresh-readiness classification before main refresh.
15
+ # portability:
16
+ # class: reusable
17
+ # targets:
18
+ # - llm-workbench
19
+ # used_by:
20
+ # - id: chat.workflows.chat-refresh-from-main
21
+ # path: .agentic/00.chat/workflows/chat-refresh-from-main.md
22
+ # - id: chat.script.main-refresh.classify-refresh-readiness
23
+ # path: scripts/00.chat/main-refresh/classify-refresh-readiness/script.sh
24
+ # effects:
25
+ # - branches
26
+ # - commits
27
+ # - writes-files
28
+
29
+ fail() {
30
+ echo "FAIL: $*" >&2
31
+ exit 1
32
+ }
33
+
34
+ SOURCE_ROOT="$(git rev-parse --show-toplevel)"
35
+ TMP_ROOT="$(mktemp -d "${TMPDIR:-/tmp}/main-refresh-classifier-smoke.XXXXXX")"
36
+
37
+ cleanup() {
38
+ rm -rf "$TMP_ROOT"
39
+ }
40
+
41
+ trap cleanup EXIT
42
+
43
+ REPO="$TMP_ROOT/repo"
44
+ SESSION_ID="2026-06-17-00-00-test-chat"
45
+ SESSION_LOG="commitLogs/2026/jun/17/${SESSION_ID}/README.md"
46
+ OTHER_LOG="commitLogs/2026/jun/17/other-chat/README.md"
47
+
48
+ mkdir -p \
49
+ "$REPO/scripts/00.chat/reporting/generate-commit-log-summary" \
50
+ "$REPO/scripts/00.chat/session-log/paths" \
51
+ "$REPO/$(dirname "$SESSION_LOG")" \
52
+ "$REPO/$(dirname "$OTHER_LOG")"
53
+
54
+ cp "$SOURCE_ROOT/scripts/00.chat/session-log/paths/lib.sh" \
55
+ "$REPO/scripts/00.chat/session-log/paths/lib.sh"
56
+ cp "$SOURCE_ROOT/scripts/00.chat/reporting/generate-commit-log-summary/script.sh" \
57
+ "$REPO/scripts/00.chat/reporting/generate-commit-log-summary/script.sh"
58
+ mkdir -p "$REPO/scripts/00.chat/main-refresh/classify-refresh-readiness"
59
+ cp "$SOURCE_ROOT/scripts/00.chat/main-refresh/classify-refresh-readiness/script.sh" \
60
+ "$REPO/scripts/00.chat/main-refresh/classify-refresh-readiness/script.sh"
61
+
62
+ git -C "$REPO" init -q -b main
63
+ git -C "$REPO" config user.name "Smoke Test"
64
+ git -C "$REPO" config user.email "smoke@example.invalid"
65
+
66
+ cat > "$REPO/README.md" <<'EOF'
67
+ base
68
+ EOF
69
+
70
+ cat > "$REPO/$SESSION_LOG" <<EOF
71
+ # Chat Session: ${SESSION_ID}
72
+
73
+ <!-- agentic-session
74
+ id: ${SESSION_ID}
75
+ chat_duration: 10s
76
+ estimated_chat_tokens: 50 tokens
77
+ -->
78
+ EOF
79
+
80
+ (
81
+ cd "$REPO"
82
+ bash scripts/00.chat/reporting/generate-commit-log-summary/script.sh --output "$TMP_ROOT/base-summary.md" >/dev/null
83
+ )
84
+
85
+ git -C "$REPO" add .
86
+ git -C "$REPO" commit -q -m "base"
87
+ git -C "$REPO" switch -q -c "chat/${SESSION_ID}"
88
+
89
+ classification() {
90
+ (
91
+ cd "$REPO"
92
+ bash scripts/00.chat/main-refresh/classify-refresh-readiness/script.sh
93
+ ) | sed -n 's/^classification=//p' | head -n 1
94
+ }
95
+
96
+ if [ "$(classification)" != "clean" ]; then
97
+ fail "clean worktree was not classified as clean"
98
+ fi
99
+
100
+ cat > "$REPO/$OTHER_LOG" <<'EOF'
101
+ # Chat Session: other-chat
102
+
103
+ <!-- agentic-session
104
+ id: other-chat
105
+ chat_duration: 20s
106
+ estimated_chat_tokens: 75 tokens
107
+ -->
108
+ EOF
109
+
110
+ git -C "$REPO" add "$OTHER_LOG"
111
+ git -C "$REPO" commit -q -m "add other log"
112
+ printf '\nlocal note\n' >> "$REPO/$SESSION_LOG"
113
+
114
+ if [ "$(classification)" != "current-session-bookkeeping" ]; then
115
+ fail "current session changes were not classified as current-session-bookkeeping"
116
+ fi
117
+
118
+ git -C "$REPO" restore -- "$SESSION_LOG"
119
+ printf '\nrepo work\n' >> "$REPO/README.md"
120
+
121
+ if [ "$(classification)" != "repo-work" ]; then
122
+ fail "repo work was not classified as repo-work"
123
+ fi
124
+
125
+ git -C "$REPO" restore -- README.md
126
+ printf '\nother evidence\n' >> "$REPO/$OTHER_LOG"
127
+
128
+ if [ "$(classification)" != "unsupported-dirty" ]; then
129
+ fail "other session log was not classified as unsupported-dirty"
130
+ fi
131
+
132
+ echo "main refresh dirty classifier smoke test passed."