Tags: PsychQuant/issue-driven-development
Tags
chore: marketplace.json 同步到 3.0.0 plugin.json 在 PR #327 裡升到 3.0.0,但這個 repo 自己的 marketplace.json 還停在 2.112.0 —— 跑 /plugin update 的使用者會看到舊版號,拿不到這次的 breaking 契約變更。 release-flow 規則講的正是這個尾巴:release 只做了一半,直到 marketplace 同步為止。 版號與 description 都從 plugin.json 取,避免兩邊各自維護又漂移。
fix: stop reconstructing perspective-writer's rules path; read and di… …sclose status R4 hardcoded `.claude/rules/correspondence-<person>.md` and only handed a path over if that file existed. Upstream moved to a three-source resolution order after 3.0.0, so in most current workspaces that path does not exist — nothing gets handed over, upstream returns status=generic, and the reply posts uncalibrated while the rules sit in a skill beside it. Verified live, not hypothetical: in a workspace using skill-packaged rules the path is absent and calibration silently does nothing. - Hand over only `recipient`; let upstream resolve (needs perspective-writer >= 4.2.0, which added subject-based resolution for exactly this). - Do NOT restate the resolution order here. A second copy in a second repo drifts, and cross-repo drift is caught by nothing. - Pin MIN_PW_CONTRACT=4.2.0 with `sort -V`. Lexical comparison is wrong in both directions: 2.11.0 sorts before 2.9.2, and 4.10.0 sorts before 4.2.0. - Read the returned status header and disclose status=generic. That draft reads normally and is indistinguishable from a calibrated one; the header is the only signal, so not consuming it means the failure mode does not exist. - Version shortfall degrades, it does not refuse. Soft integration's posture is "works when absent"; refusing would cost the reply itself to save a calibration. Honest limit recorded inline: status=generic cannot distinguish "no rules on file yet" from "rules exist but were not reached" — upstream returns one value for both (their #6 known residual). The disclosure is therefore neutral and does not imply an error. Refs #289
fix: stop reconstructing perspective-writer's rules path; read and di… …sclose status R4 hardcoded `.claude/rules/correspondence-<person>.md` and only handed a path over if that file existed. Upstream moved to a three-source resolution order after 3.0.0, so in most current workspaces that path does not exist — nothing gets handed over, upstream returns status=generic, and the reply posts uncalibrated while the rules sit in a skill beside it. Verified live, not hypothetical: in a workspace using skill-packaged rules the path is absent and calibration silently does nothing. - Hand over only `recipient`; let upstream resolve (needs perspective-writer >= 4.2.0, which added subject-based resolution for exactly this). - Do NOT restate the resolution order here. A second copy in a second repo drifts, and cross-repo drift is caught by nothing. - Pin MIN_PW_CONTRACT=4.2.0 with `sort -V`. Lexical comparison is wrong in both directions: 2.11.0 sorts before 2.9.2, and 4.10.0 sorts before 4.2.0. - Read the returned status header and disclose status=generic. That draft reads normally and is indistinguishable from a calibrated one; the header is the only signal, so not consuming it means the failure mode does not exist. - Version shortfall degrades, it does not refuse. Soft integration's posture is "works when absent"; refusing would cost the reply itself to save a calibration. Honest limit recorded inline: status=generic cannot distinguish "no rules on file yet" from "rules exist but were not reached" — upstream returns one value for both (their #6 known residual). The disclosure is therefore neutral and does not imply an error. Refs #289
fix(idd-comment,gh-egress): tier floor is a minimum, not a replacemen… …t — verify round 1 6-AI verify round 1 (4 lens + Codex + DA) findings, all folded: - HIGH (Codex + DA concur): SKILL R1 read "after confirmation dispatch at --scrub-attested warn" — a pinned level that would silently DOWNGRADE a third-party repo's ENFORCE tier. Rewrote as floor semantics: effective tier = max(repo-derived tier, warn); ENFORCE never downgrades, block-with-diff runs unchanged. Spec: warn-proceed scenario qualified to LIGHT/WARN repos + new enforce-preservation scenario. - HIGH/MED (Codex + DA): layer-1 "already on same repo remote" premise was unguaranteed — a cross-repo comment URL is a new cross-audience disclosure. SKILL + spec: layer-1 exemption requires the URL to belong to the destination repo; cross-repo URLs resolve as layer 3 (marker records user-pasted) and carry the floor. New spec scenario. - MED: rules/header reclassification — items 1-3 are level-independent zero-tolerance nets; item 4 is a level-dependent tier-floor attestation check (the blanket "LEVEL-INDEPENDENT"/"zero-tolerance" claims no longer held). gh-egress header now enumerates all 4 items. - MED: honest raw-substring wording (two fixed-string token matches over raw prose, fences not stripped, NO backtick escape hatch — the entity-@ parity claim was inaccurate on that dimension) + accepted-friction LOCK test (fenced discussion body at light → 13). - MED (DA N-2): SKILL Step 4 now takes the floor max() before attesting — the SKILL side is the primary gate for own-private, not just the wrapper bounce. MED (DA N-4): template↔wrapper token binding assertions (silently- disabled-net risk). Conjunction negative fixture (user-pasted without type=reply → dispatch) + stderr remediation assertion. - LOW: grep -Fq -- hardening; "body needs no redaction" wording softened; design/tasks append-only + R1/R4 claims corrected to match reality. Tests: gh-egress 66, idd-comment-reply 35, aggregator 40 suites 0 fail. Refs #272
fix(idd-comment): reconcile reply-type contract per 6-AI verify round 1 Verify round 1 (4 lens + Codex + Devil's Advocate) findings, all folded: - DA-1 (HIGH): verify-before-claim was issue-level (git log --grep "#N") but the obligation is per-point. Rewrote R2: the grep is an entry point; the found commit/PR must actually contain the change addressing THAT point, and finding any #N commit must not mark all points resolved. Locked by 2 new drift-guard assertions. - Codex + Regression F1: --points-from "required" vs spec "when unspecified default to issue-body" was a genuine contradiction. Reworded spec so the three layers describe how the REQUIRED value resolves (issue-body is an explicit sentinel), not a default for an absent flag. Dropped --body from reply's 必填 column (Step 2 + spec make it optional). - DA-2 (MEDIUM): bootstrap TaskCreate order (build_comment_body before resolve/verify) contradicted the pipeline "順序是契約". Reordered so resolve_points_source + verify_before_claim precede build_comment_body (= R3 anchoring) and annotated the dependency. - Security F4 + DA-3 (MEDIUM): reply is the only type reproducing third-party verbatim. Added scrub-wins-over-verbatim clause + noted SCRUB_LEVEL is repo-visibility-keyed (own-repo → warn/light, never enforce) so layer-3 pasted external content needs heightened self-review, not tier default. - Test strengthening (Logic LOW-1 / Requirements F3 / Codex gaps): anchored the weak "reply" docs needle, added assertions for layer-1 URL / layer-3 paste / per-point template elements / degrade post-anyway / scrub-wins. Suite 19 -> 27 assertions. - Doc drift: design/proposal run.sh -> test.sh, suite count 39->40. run-all-tests: 40 suites 0 fail. reply suite 27/27. spectra valid. Refs #269
chore: release issue-driven-dev v2.94.0 (selective git auto-tag) Ships #85 — idd-issue tags idd-{N}-baseline (rollback anchor), idd-verify tags idd-{N}-verified on Aggregate PASS (review snapshot); config auto_tag (default-on, opt-out), idempotent + graceful-skip. Minor bump for the new capability. Bumps plugin.json + marketplace.json to 2.94.0; adds CHANGELOG entry + README Version History row. Refs #85