For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
| 項目 | 內容 |
|---|---|
| 緣由 | 2026-05-26 user 用 mf b8065ad5 + 亞航-CMMC-SSP-20260520-1.docx 跑 template-edit docx import,三個問題:(S) components/leveraged 沒匯入 DB(DB 0 row 但 docx 解出 4+1);(T) 部分 STEP 2 選 keep_current 的 party 鉤稽(responsible_party link)被砍;(U) FE confirm payload 完全沒帶 4 個 v3 decision keys |
| Branch | feature/ssp-oscal-alignment |
| Bug 編號 | S = stale-link cleanup 砍 keep_current;T = v2-bundle silent fail;U = FE 漏 v3 decisions wire |
| 預估時間 | 4-6 小時(含 Phase 0 verify + 3 個 fix + manual E2E) |
Goal: 修 docx import → mf template-edit 流程的 3 個 bug,讓 user 在 STEP 2 選的 use_docx / keep_current 決策都正確生效,且 components / leveraged / inventory 真實寫入 DB。
Architecture: Phase 0 先 patch BE 加 debug log + 請 user 重啟 + 重做一次 import 才 pin Bug T 確切位置;Phase 1-3 順序 fix S/T/U;Phase 4 manual E2E;Phase 5 收尾(等 user 下令才 commit 收尾文件)。
Tech Stack: Python 3.11 / Flask / SQLAlchemy / dependency-injector / Vue 3 / Pinia
# 1. branch + working tree
git -C ~/Projects/Billows/Audit-Manager/compliance-manager-be branch --show-current
# 預期:feature/ssp-oscal-alignment
git -C ~/Projects/Billows/Audit-Manager/compliance-manager-fe branch --show-current
# 預期:feature/ssp-oscal-alignment
git -C ~/Projects/Billows/Audit-Manager/compliance-manager-be status --short | grep -E '\.py$|\.md$' | head -20
git -C ~/Projects/Billows/Audit-Manager/compliance-manager-fe status --short
# 2. BE listener
lsof -t -i:8000 && echo "BE up" || echo "BE down — restart needed"
# 3. BE smoke tests
cd ~/Projects/Billows/Audit-Manager/compliance-manager-be
poetry run pytest tests/test_ssp_docx_import_app_service.py tests/test_ssp_docx_diff_service.py tests/test_ssp_write_strategy.py tests/test_module_frame_write_strategy_v2_parties.py -q
# 預期:全 passfeedback_plan_vs_reality_verify_first)# A. 確認 mf 343 + SSP shell 219/228 + components/leveraged 0 row
PGPASSWORD='jedi@123!' psql -h 192.168.50.188 -p 25432 -U cmmgr -d guidant_ai_dev -A -F$'\t' -c "
SET app.is_super_admin='t';
SELECT mf.id, mf.uid, mf.name FROM public.module_frames mf WHERE mf.uid='b8065ad5-e169-4df4-9bd3-5ec0d03b2e1d';
SELECT ssp.id, ssp.uid FROM oscal.system_security_plans ssp WHERE ssp.template_module_frame_id=343;
SELECT 'comp' k, count(*) FROM oscal.ssp_components WHERE ssp_id IN (219,228);
SELECT 'la' k, count(*) FROM oscal.ssp_leveraged_authorizations WHERE ssp_id IN (219,228);
SELECT 'rp_mf' k, count(*) FROM oscal.oscal_responsible_parties WHERE context_type='module_frame' AND context_id=343;
"
# 預期:mf=343, shell=219+228, comp=0, la=0, rp_mf=5
# B. 確認 parse_job 223 含 v2-bundle + components=4 + leveraged=1
PGPASSWORD='jedi@123!' psql -h 192.168.50.188 -p 25432 -U cmmgr -d guidant_ai_dev -A -F$'\t' -c "
SET app.is_super_admin='t';
SELECT id, status, (parsed_result->>'schema_version') schema,
jsonb_array_length(parsed_result->'components') comp_n,
jsonb_array_length(parsed_result->'leveraged_authorizations') la_n
FROM oscal.ssp_docx_parse_jobs WHERE id=223;
"
# 預期:comp_n=4, la_n=1, schema=v2-bundle
# C. 確認 ModuleFrameWriteStrategy.write_parties 仍有 L539-544 stale-link cleanup
grep -nA 6 'existing_link_map.items' ~/Projects/Billows/Audit-Manager/compliance-manager-be/domain/oscal/strategy/module_frame_write_strategy.py
# 預期:line 540-544 顯示 `if uuid not in processed_uuids: delete_by_id`
# D. 確認 FE SspDocxImportPage L736-744 payload 仍漏 4 個 v3 keys
grep -A 10 'const payload = {' ~/Projects/Billows/Audit-Manager/compliance-manager-fe/src/components/grc/ssp-docx-import-v2/SspDocxImportPage.vue
# 預期:只看到 decisions / parties_decisions,沒看到 components_decisions / la_decisions / inventory_items_decisions / system_characteristic_decision
# E. 確認 sspDocxImportStore.buildConfirmPayload 已正確帶 4 個 v3 keys(之後 FE 改用它)
grep -nA 6 'buildConfirmPayload' ~/Projects/Billows/Audit-Manager/compliance-manager-fe/src/stores/sspDocxImportStore.js
# 預期:line ~214 包 components_decisions / leveraged_authorizations_decisions / inventory_items_decisions / system_characteristic_decision任一條 verify 不符 → 停下回報 user,不開工。
Bug T silent-fail 在
confirm_service.confirm()內某處,inline reproduction 失敗(DI deepcopy block),改 patch BE 加 5 行 debug log 後重啟 → 請 user 重做一次 import → 看 log。
_run_v2_bundle_confirm 加 debug logFiles:
app/oscal/service/ssp_docx_import_app_service.py:791-897加在 L819 if self._confirm_service is None: 之前:
self._safe_log_info(
"[v2-bundle-debug] _run_v2_bundle_confirm enter: confirm_service=%s shell_service=%s "
"source_type=%s source_uid=%s parsed_components=%d parsed_la=%d parsed_inv=%d sc=%s",
"wired" if self._confirm_service is not None else "None",
"wired" if self._ssp_shell_service is not None else "None",
source_type,
effective_source_uid,
len(parsed_result.get("components") or []),
len(parsed_result.get("leveraged_authorizations") or []),
len(parsed_result.get("inventory_items") or []),
"present" if parsed_result.get("system_characteristic") else "None",
)加在 L865 if ssp_id is None: 之前(ensure_shell 成功時記下 ssp_id):
if source_type == "module_frame" and ssp_id is not None:
self._safe_log_info(
"[v2-bundle-debug] ensure_shell OK ssp_id=%s", ssp_id,
)加在 L872 result = self._confirm_service.confirm(...) 前後:
self._safe_log_info(
"[v2-bundle-debug] calling _confirm_service.confirm ssp_id=%s parsed_components=%d parsed_la=%d parsed_inv=%d",
ssp_id,
len(parsed_result.get("components") or []),
len(parsed_result.get("leveraged_authorizations") or []),
len(parsed_result.get("inventory_items") or []),
)
result = self._confirm_service.confirm(
parsed_result=parsed_result,
ssp_id=ssp_id,
catalog_id=catalog_id,
user_context=user_context,
)
self._safe_log_info(
"[v2-bundle-debug] _confirm_service.confirm returned: %s", result,
)Files:
domain/oscal/import_pipeline/confirm_service.py:41-115加在 L52 bundle = dict_to_bundle(parsed_result) 後 + L84 / L89 / L98 write 之前:
logger.info(
"[v2-bundle-debug] confirm: bundle.parsed_components=%d parsed_la=%d parsed_inv=%d parsed_parties=%d",
len(bundle.parsed_components),
len(bundle.parsed_leveraged_authorizations),
len(bundle.parsed_inventory_items),
len(bundle.parsed_parties),
)
# ... existing normalize ...
logger.info(
"[v2-bundle-debug] confirm post-normalize: bundle.parsed_components=%d parsed_la=%d parsed_inv=%d",
len(bundle.parsed_components),
len(bundle.parsed_leveraged_authorizations),
len(bundle.parsed_inventory_items),
)並在每個 self._leveraged.write(...) / self._component.write(...) / self._inventory.write(...) 後 log return value。
請重啟 BE(patch 加了 debug log)。然後請:
1. 用 mf b8065ad5 跑一次 import-docx 上傳同一份 docx
2. STEP 2 全選「採用新值」
3. STEP 3 確認後按確認匯入
我會從 log 找確切 silent fail 位置。
grep -nE '\[v2-bundle-debug\]' ~/Projects/Billows/Audit-Manager/compliance-manager-be/log/app.log | tail -30從 log 看出:
_run_v2_bundle_confirm enter 顯示 parsed_components 是否非 0confirm enter 跟 post-normalize 之間 bundle.parsed_components 變化不 commit 這個 patch(debug 用,root cause pin 後拿掉,per Task 2.5)。
_filter_parties_for_write對 keep_current 不收進 list(只收 use_docx),但write_partiesL539-544 把existing_link_map內所有未在processed_uuids的 link 砍掉 — 副作用是 mix-decision 場景(部分 use_docx 部分 keep_current)會誤砍 keep_current 的 link。
Files:
domain/oscal/strategy/module_frame_write_strategy.py:471-546tests/test_module_frame_write_strategy_v2_parties.py# tests/test_module_frame_write_strategy_v2_parties.py 內加
def test_write_parties_does_not_unlink_existing_when_called_with_subset(
strategy, mock_mf, mock_party_repo, mock_responsible_party_repo,
):
"""write_parties 收到部分 parties 不該砍掉 existing_link 內未提交的 link。
場景:mf 已有 3 個 parties (A, B, C)。Caller 只傳 A 進 write_parties
(B/C 是 keep_current,由 caller 過濾掉)。預期:A 被 upsert,B/C link
保留。Bug S:原本 L539-544 cleanup 把 B/C link 都砍掉。
"""
# arrange existing 3 links (A, B, C)
from jedi_oscal.domain.entity.base.oscal_responsible_party_entity import ResponsiblePartyEntity
mock_responsible_party_repo.get_all.return_value = [
MagicMock(id=1, party_uuid="uuid-A"),
MagicMock(id=2, party_uuid="uuid-B"),
MagicMock(id=3, party_uuid="uuid-C"),
]
# _upsert_party returns existing party A entity
mock_party_repo.get_one.return_value = MagicMock(uid="uuid-A")
# act: only A is in parties list
from domain.oscal.parser.ssp_intermediate import ParsedParty
parties = [ParsedParty(name="A", party_type="person", role="system-owner")]
written = strategy.write_parties(parties, source_uid=mock_mf.uid, user_id="tester")
# assert: B/C delete_by_id 不該被呼叫
delete_calls = mock_responsible_party_repo.delete_by_id.call_args_list
deleted_ids = [c.args[0] for c in delete_calls]
assert 2 not in deleted_ids, "B link should NOT be unlinked (keep_current)"
assert 3 not in deleted_ids, "C link should NOT be unlinked (keep_current)"
assert written == 1poetry run pytest tests/test_module_frame_write_strategy_v2_parties.py::test_write_parties_does_not_unlink_existing_when_called_with_subset -v預期:FAIL(delete_by_id 被 call 砍 B/C link)
_collect_parties_to_unlink 處理)修改後的 method body(L506-546 替換為):
written = 0
for parsed in parties:
party_entity = self._upsert_party(parsed, user_id)
if party_entity is None:
continue
party_uid = str(
getattr(party_entity, "uid", None) or getattr(party_entity, "uuid", "") or ""
)
self._upsert_responsible_party(
role_id=parsed.role or "",
party_uid=party_uid,
context_type="module_frame",
context_id=module_frame_id,
)
written += 1
# Note (Bug S fix 2026-05-26): 不再做 stale-link cleanup。caller
# (_collect_parties_to_unlink) 已明確收集 diff_status='gone' + action='use_docx'
# 的 party_uids 走 unlink_parties path。在 write_parties 內依「沒在
# processed_uuids」推論 stale 是錯的 — 因為 caller 對 keep_current 的
# party 也不會送進 parties list(用 SspWriteStrategy 同樣 pattern,
# 它本來就沒這個 cleanup)。
return written對應拿掉 from jedi_oscal.domain.entity.base.oscal_responsible_party_query_entity import ResponsiblePartyQueryEntity import(如果本 method 不再用)— grep 確認 import 仍被其他 method 用(unlink_parties 用到)→ 保留 import。
poetry run pytest tests/test_module_frame_write_strategy_v2_parties.py::test_write_parties_does_not_unlink_existing_when_called_with_subset -v預期:PASS
poetry run pytest tests/test_module_frame_write_strategy_v2_parties.py tests/test_ssp_docx_import_app_service.py tests/test_ssp_write_strategy.py -q預期:全 pass
git -C ~/Projects/Billows/Audit-Manager/compliance-manager-be add \
domain/oscal/strategy/module_frame_write_strategy.py \
tests/test_module_frame_write_strategy_v2_parties.py
git -C ~/Projects/Billows/Audit-Manager/compliance-manager-be commit -m "$(cat <<'EOF'
fix(ssp-oscal-alignment): Bug S — ModuleFrameWriteStrategy.write_parties 不再砍 keep_current link
Root cause: L539-544 stale-link cleanup 對 caller 沒送進來的 party_uuid
直接 delete_by_id — caller (`_filter_parties_for_write`) 對 keep_current
party 不收進 list 是預期行為,cleanup 卻把這些「沒寫入」誤判為「該砍」。
副作用:mix-decision 場景(部分 use_docx + 部分 keep_current)會把
keep_current 的 responsible_party link 砍掉 → user 在 template-edit
看不到 → 以為「鉤稽資料被刪除」。
Fix: 拿掉 existing_link_map / processed_uuids stale cleanup。caller 端
`_collect_parties_to_unlink` 已明確收集 diff_status='gone' + action='use_docx'
走 unlink_parties path,write_parties 不該自作主張砍 link
(mirror SspWriteStrategy.write_parties — 本來就沒這個 cleanup)。
Test: tests/test_module_frame_write_strategy_v2_parties.py 加
test_write_parties_does_not_unlink_existing_when_called_with_subset。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
EOF
)"必前置完成 Phase 0 — 拿到 debug log 確切位置才能寫 fix。
從 Phase 0 grep 結果應該看到下列其中一條:
| 觀察 | Root cause | Fix 方向 |
|---|---|---|
[v2-bundle-debug] _run_v2_bundle_confirm enter: parsed_components=0 |
_apply_v3_decisions 把 parsed_result['components'] 弄空 |
修 _apply_v3_decisions |
_run_v2_bundle_confirm enter: parsed_components=4 但 confirm: bundle.parsed_components=0 |
dict_to_bundle silent skip |
修 bundle_restore._restore_component |
confirm: bundle.parsed_components=4 但 _confirm_service.confirm returned: written_components=0 |
_component.write() per-row insert 全失敗(logger 沒寫 app.log) |
補 logger config / 修 insert |
_confirm_service.confirm returned: written_components=4 但 DB 還是 0 row |
transaction rollback 在更晚 step | 找 transaction boundary |
沒看到 _run_v2_bundle_confirm enter log |
confirm_import 整個 try block 抓到 exception 沒走進 v2-bundle | 看 confirm_import line 760 try block |
範例(假設 root cause 是 _apply_v3_decisions 在 components_decisions=[] 時把 components 弄空 — inline repro 證偽,所以這條候選低):
# tests/test_ssp_docx_import_app_service.py 加
def test_v2_bundle_confirm_writes_components_when_decisions_empty(
app_service, mock_confirm_service, sample_parsed_result_with_components,
):
"""FE 沒送 components_decisions / la_decisions 時,BE 應該仍寫入 docx 帶來的
components/leveraged(mirror added × None default → use_docx semantics)。
"""
# arrange parsed_result 帶 4 個 components + 1 個 leveraged
job = MagicMock(parsed_result=sample_parsed_result_with_components,
source_type="module_frame", source_uid="mf-uid",
status="awaiting_review", mode="statement_only")
# ... fixture
# act
app_service.confirm_import(parse_uid="job-uid", payload={
"decisions": [], "parties_decisions": [],
"components_decisions": [], # 空
"leveraged_authorizations_decisions": [],
"source_uid": "mf-uid",
}, user_context=mock_user_context)
# assert
args, _ = mock_confirm_service.confirm.call_args
assert len(args[0]["components"]) == 4, "components shouldn't be wiped"
assert len(args[0]["leveraged_authorizations"]) == 1poetry run pytest tests/test_ssp_docx_import_app_service.py::test_v2_bundle_confirm_writes_components_when_decisions_empty -vpoetry run pytest tests/ -qgrep -nE '\[v2-bundle-debug\]' app/oscal/service/ssp_docx_import_app_service.py domain/oscal/import_pipeline/confirm_service.py
# 應該沒輸出poetry run pytest tests/test_ssp_docx_import_app_service.py -qgit -C ~/Projects/Billows/Audit-Manager/compliance-manager-be add \
<修改的檔案們>
git -C ~/Projects/Billows/Audit-Manager/compliance-manager-be commit -m "$(cat <<'EOF'
fix(ssp-oscal-alignment): Bug T — v2-bundle confirm silent fail 0 row components/leveraged
Root cause: <根據 Phase 0 結論填>
Fix: <根據 fix code 填>
Test: tests/test_ssp_docx_import_app_service.py 加
test_v2_bundle_confirm_writes_components_when_decisions_empty。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
EOF
)"
SspDocxImportPage.vueL736-744 手刻 payload,沒 wirecomponents_decisions/leveraged_authorizations_decisions/inventory_items_decisions/system_characteristic_decision。store 的buildConfirmPayload()已正確含這 4 個 keys 但沒被用。
Files:
compliance-manager-fe/src/components/grc/ssp-docx-import-v2/SspDocxImportPage.vue:617-744head -200 ~/Projects/Billows/Audit-Manager/compliance-manager-fe/CLAUDE.md// 在 L736 const payload = { 內加:
const components_decisions = Object.entries(diffStore.decisions.components || {}).map(
([row_uid, d]) => ({ row_uid, action: d.action ?? 'skip' })
)
const leveraged_authorizations_decisions = Object.entries(diffStore.decisions.leveraged_authorizations || {}).map(
([row_uid, d]) => ({ row_uid, action: d.action ?? 'skip' })
)
const inventory_items_decisions = Object.entries(diffStore.decisions.inventory_items || {}).map(
([row_uid, d]) => ({ row_uid, action: d.action ?? 'skip' })
)
const system_characteristic_decision = diffStore.decisions.system_characteristic?.action ?? null
const payload = {
decisions,
parties_decisions,
components_decisions,
leveraged_authorizations_decisions,
inventory_items_decisions,
system_characteristic_decision,
manual_assignments: [],
skipped_paragraph_idxs: [],
predicted_controls_user_selection: parsedResult.value?.predicted_module_frame_controls || [],
source_uid: effectiveTargetUid || props.targetUid || undefined,
content_overrides: contentOverrides,
}
cd ~/Projects/Billows/Audit-Manager/compliance-manager-fe
npm run lint -- src/components/grc/ssp-docx-import-v2/SspDocxImportPage.vue預期:no error
git -C ~/Projects/Billows/Audit-Manager/compliance-manager-fe add \
src/components/grc/ssp-docx-import-v2/SspDocxImportPage.vue
git -C ~/Projects/Billows/Audit-Manager/compliance-manager-fe commit -m "$(cat <<'EOF'
fix(ssp-oscal-alignment): Bug U — confirm payload 補 4 個 v3 decision keys
Root cause: SspDocxImportPage.vue L736-744 手刻 confirm payload,沒帶
components_decisions / leveraged_authorizations_decisions /
inventory_items_decisions / system_characteristic_decision。
diffStore.buildConfirmPayload 已正確含這 4 keys 但沒被使用。
BE 端 _apply_v3_decisions 對「沒給 decision」走 backfill cur path —
若 current 為空 final_list 也空 → components 永遠不寫入。
Fix: payload 內補 4 個 v3 keys 從 diffStore.decisions 收集。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
EOF
)"Phase 1-3 BE + FE fix 完成。請:
1. 重啟 BE(service 層改了)— 不要直接吃 cache,用 kill -9 找 :8000 listener
2. FE: cd ~/Projects/Billows/Audit-Manager/compliance-manager-fe && npm run dev(如果還沒起)
3. 走完整流程:
(a) 開 /module-frame/b8065ad5-e169-4df4-9bd3-5ec0d03b2e1d/template-edit 看 parties 5 個 + components 0 個(baseline)
(b) 上 /module-frame/b8065ad5-e169-4df4-9bd3-5ec0d03b2e1d/import-docx 上傳同份 docx
(c) STEP 2 全選「採用新值」(含 components / leveraged tab)
(d) STEP 3 確認後按確認匯入
(e) 回 template-edit 確認 components 出現 4 個 + leveraged 出現 1 個
(f) 再做一次同樣動作但 STEP 2 部分 party 改選「保留現值」(mix scenario)
(g) 確認保留現值的 party 鉤稽資料 + link 都還在
PGPASSWORD='jedi@123!' psql -h 192.168.50.188 -p 25432 -U cmmgr -d guidant_ai_dev -A -F$'\t' -c "
SET app.is_super_admin='t';
SELECT 'comp_after' k, count(*) FROM oscal.ssp_components WHERE ssp_id IN (219, 228);
SELECT 'la_after' k, count(*) FROM oscal.ssp_leveraged_authorizations WHERE ssp_id IN (219, 228);
SELECT 'rp_mf_after' k, count(*) FROM oscal.oscal_responsible_parties WHERE context_type='module_frame' AND context_id=343;
SELECT p.id, p.name, p.user_id, p.org_unit_id FROM oscal.oscal_parties p
JOIN oscal.oscal_responsible_parties rp ON rp.party_uuid = p.uid::text
WHERE rp.context_type='module_frame' AND rp.context_id=343 ORDER BY p.id;
"預期(fix 成功):
comp_after >= 4(兩個 shell 合計)la_after >= 1rp_mf_after = 5(不少不多)不符 → STOP,回 root cause Phase 0 重新 verify。
per memory
feedback_wait_for_user_command_to_close.md:fix code commit 完只給 user 一句話 status + 手測 checklist。預先寫好的 BE docs 留 working tree 不 commit。user verify pass + 明確下令才 stage + commit 收尾文件。
涵蓋:Bug S/T/U root cause + commits + 教訓
frontmatter type=fix,modules=[oscal, ssp-docx-import, frontend],commit=<填 BE/FE hash>
write_strategy.write_parties 不該在 caller 沒傳進來時自作主張砍 link — caller (
_collect_parties_to_unlink) 已明確收集要砍的,write strategy 只負責「caller 給的這批寫入」。Bug S 踩過 mf strategy 內 stale cleanup 砍 keep_current link,造成鉤稽資料消失。SspWriteStrategy 本來就沒這 cleanup(對的)。
FE 對 BE confirm/submit payload 要走 store 統一的 buildXxxPayload(),不要在 view 內手刻 — store 已維護完整 schema,view 手刻容易漏 key(Bug U 漏 4 個 v3 decision keys 兩個月)。新增 BE accept 的 payload key 後,先驗 store builder 有沒有,再驗 view 是否用 builder。
python3 scripts/extract_claude_sessions.py --date 2026-05-26 --topic bug-stu-docx-import-components --autodocs/features/FR-028-2605-ssp-oscal-alignment/handoff/2026-05-25-bug-r-diff-service-duplicate-entry-handoff.md(如果本期 fix 涵蓋這些)docs/features/FR-028-2605-ssp-oscal-alignment/implementation-plan-bug-pqr.mddocs/features/FR-028-2605-ssp-oscal-alignment/implementation-plan-bug-r-deeper.mddocs/claude/frontend-overview.md — FE buildConfirmPayload pattern 新增說明(若先前沒提)docs/api/oscal/api-spec.md — confirm endpoint payload 加 4 個 v3 keys 文件化git -C ~/Projects/Billows/Audit-Manager/compliance-manager-be add \
docs/features/FR-028-2605-ssp-oscal-alignment/design.md \
docs/changelog/2026-05-26-fix-bug-stu-*.md \
docs/features/FR-028-2605-ssp-oscal-alignment/handoff/2026-05-26-bug-stu-FIXED-SUMMARY.md \
docs/features/FR-028-2605-ssp-oscal-alignment/handoff/2026-05-25-bug-r-diff-service-duplicate-entry-handoff.md \
docs/conversation-history/2026-05-26/bug-stu-docx-import-components/ \
docs/claude/frontend-overview.md \
docs/api/oscal/api-spec.md
git -C ~/Projects/Billows/Audit-Manager/compliance-manager-be commit -m "$(cat <<'EOF'
docs(ssp-oscal-alignment): Bug S/T/U 收尾橫向文件更新
- design.md §11.39 + §11 index 補 Bug S/T/U 三 bug 紀錄
- changelog: 2026-05-26-fix-bug-stu-docx-import-components-and-keep-current.md
- handoff: 2026-05-26-bug-stu-FIXED-SUMMARY.md 收尾報告
- 對話歷史歸檔 → docs/conversation-history/2026-05-26/bug-stu-docx-import-components/
- frontend-overview.md / api-spec.md 同步本期改動
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
EOF
)"收尾 commit 完成。BE 領先 origin <N> commits(Phase 1 + Phase 2 + Phase 5),
FE 領先 origin <M> commits(Phase 3)。要 push 哪個 repo?(per CLAUDE.md
「push 永遠要 user 明確指示」)
feedback_no_branch_switch)feedback_stage_commit_no_ask)feedback_be_restart_after_service_change)oscal_responsible_parties + ssp_components)python main_socketio.py)feedback_no_chinglish)-am)請閱讀並執行 implementation plan:
docs/features/FR-028-2605-ssp-oscal-alignment/implementation-plan-bug-stu.md
3 個 bug:(S) ModuleFrameWriteStrategy 砍 keep_current link;
(T) v2-bundle confirm 寫 0 row components;(U) FE 漏 4 個 v3 decisions wire。
按 Phase 0 → 1 → 2 → 3 → 4 → 5 順序。Phase 0 必先 patch debug log 請
user 重啟 + 重做 1 次 import → pin Bug T 確切位置才能往 Phase 2 寫 fix。
注意行為規範:不切 branch / 不自動 push / 改 BE service 必提醒重啟 /
收尾等 user 下令 / 可人工驗證就切人工。