Skip to content

feat: /idd-edit runtime enforcement (R4 + R5) via extracted helper script (#154)#159

Open
kiki830621 wants to merge 1 commit into
mainfrom
idd/154-edit-runtime
Open

feat: /idd-edit runtime enforcement (R4 + R5) via extracted helper script (#154)#159
kiki830621 wants to merge 1 commit into
mainfrom
idd/154-edit-runtime

Conversation

@kiki830621
Copy link
Copy Markdown
Contributor

Refs #154 Refs #150 Refs #155 Refs #156 Refs #157 Refs #158

Summary

Closes #150 Requirements 4 + 5 runtime enforcement deferral, addressing R1/R2/R3 bash-incremental failure on PR #153 (3 verify iterations each introduced new parser bugs).

Approach (per #154 D1-D3 plan-locked decisions):

Mid-impl pivot per .claude/scripts/tests/spectra-archive-post-ic/ precedent: extract parser to .claude/scripts/idd-edit-helper.sh (proper extracted helper) instead of inline SKILL.md bash. This solves R1/R2/R3 root cause more deeply — AI no longer generates parser bash inline.

What lands

Surface Change
.claude/scripts/idd-edit-helper.sh NEW: 3 subcommands (parse-args / validate-target / section-replace), 373 lines, 5 distinct exit codes
.claude/scripts/tests/idd-edit/ NEW: fixture-dir test runner + 13 fixtures covering R1/R2/R3 regression set + R4/R5 gate cases
.../skills/idd-edit/SKILL.md Step 1+2 use helper; Step 4 --replace uses section-replace helper; argument-hint + 5 usage examples + Batch mode note
.../skills/idd-comment/SKILL.md errata Template SPECIAL BEHAVIOUR handles R5 exit 4 with helpful manual-invocation message
openspec/specs/append-vs-modify-discipline/spec.md Purpose + R4 + R5 preambles: "deferred to #154" → "landed via #154" + tested-by fixture refs
plugin.json 2.74.0 → 2.75.0
CHANGELOG.md [2.75.0] entry with 8 Added / 6 Refactored / 2 BREAKING markers

Test gate proof

$ bash .claude/scripts/tests/idd-edit/test.sh
PASS   01-scope-eq                       (eq form)
PASS   02-scope-space                    (space form)
PASS   03-scope-last-arg                 (R3 C1: --scope as last arg → exit 2)
PASS   04-scope-eats-next-flag           (R3 C2: --scope --body → exit 2)
PASS   05-body-file-missing              (R3 H1: unreadable → exit 5)
PASS   06-multi-line-body                (R3 C3: BSD awk newline OK)
PASS   07-single-line-body
PASS   08-section-with-subs              (R2 B3-NEW-3: stop at next ## not ###)
PASS   09-section-no-closing-heading     (EOF as section end)
PASS   10-replace-no-scope               (R4 gate: exit 3)
PASS   11-non-owner-no-override          (OVERRIDE=false default)
PASS   12-non-owner-with-override        (override requires --reason → exit 2)
PASS   13-errata-refuse-message          (override+reason succeeds)

Results: 13 passed, 0 failed

BREAKING (runtime)

  • /idd-edit --replace without --scope/--section now refuses (exit 3 + R4 message)
  • /idd-edit modifying non-OWNER non-bot comment now refuses (exit 4 + R5 message); /idd-comment errata flow auto-call handles gracefully

Checklist

  • Diagnose (comment)
  • Plan (comment) — EnterPlanMode approved
  • Implement (1 commit: ce0adf4)
  • Verify (run /idd-verify --pr <this-PR>)
  • Verify-gated: post-verify PASS = ready to merge → /idd-close #154 after merge

Filed mid-impl


Generated by /idd-implement on PR path. Do NOT add a GitHub close trailer (Closes/Fixes/Resolves) — IDD discipline requires manual /idd-close after merge to enforce checklist gate + closing summary.

…ript

Closes #150 Requirements 4 + 5 runtime enforcement deferral, addressing
R1/R2/R3 bash-incremental failure on PR #153 (3 verify iterations each
introduced new parser bugs).

# Approach (per #154 D1-D3 locked decisions before EnterPlanMode)

D1: PR path (this branch)
D2: Q4 errata flow → refuse-with-helpful-message (NOT auto-override),
    aligns with IC_R007 user-authored-intent spirit
D3: #156 test framework → ad-hoc shell test runner this PR + #156
    generalizes later

Mid-impl pivot per .claude/scripts/tests/spectra-archive-post-ic/
precedent: extract parser to .claude/scripts/idd-edit-helper.sh (proper
extracted helper) instead of inline SKILL.md bash (which is what kept
breaking in R1/R2/R3).

# Implementation

.claude/scripts/idd-edit-helper.sh — 3 subcommands:
- parse-args: positional shift over 7 flags + missing-value guards
  (R3 C1/C2) + eq-form support + body-file readability (R3 H1) +
  R4 gate (R4) + override-pair guard. Emits eval-friendly KEY=value
  via printf %q.
- validate-target: single gh API call, *[bot] allowlist + OWNER
  passthrough + override pathway, R5 refuse exit 4 with actionable
  message.
- section-replace: awk-getline pattern (BSD/gnu safe, closes R3 C3
  BSD awk -v multi-line newline reject).

.claude/scripts/tests/idd-edit/ — fixture-dir test runner with 13
fixtures covering R1/R2/R3 regression set + R4/R5 gate cases. All
13 GREEN.

SKILL.md changes:
- Frontmatter argument-hint reflects new flag syntax
- Step 1 + Step 2 replaced with helper script invocations
- Step 4 --replace mode uses section-replace helper
- ## 使用範例: 3 examples updated + 2 new (section-replace + errata
  override)
- ## Batch mode: per-target R4/R5 note + #158 cross-link

idd-comment/SKILL.md errata Template SPECIAL BEHAVIOUR: IDD_CALLER
env var pattern + R5 refuse exit 4 handling + helpful message
suggesting manual --override-user-content.

# Spec + version

openspec/specs/append-vs-modify-discipline/spec.md: Purpose + R4 + R5
preambles updated from 'deferred to #154' to 'landed via #154' +
specific helper subcommand + tested-by fixture refs.

plugin.json: 2.74.0 → 2.75.0.

# Filed during implementation

#155 — bash vs alternative layer (parking-lot P3)
#156 — IDD plugin test framework (P2 — partially pre-empted by reusing
  precedent)
#157 — spec.md @trace blocks no auto-updater (parking-lot P3)
#158 — /idd-edit batch + R5 semantics decision (P2)

Refs #154 Refs #150 Refs #155 Refs #156 Refs #157 Refs #158
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[META] Codify append-vs-modify discipline as plugin-level principle

1 participant