mirror of
https://github.com/Imbad0202/academic-research-skills.git
synced 2026-09-14 13:51:17 +08:00
e7e775a0e1
* feat(v3.6.7 Step 6 Phase 6.7): downstream agent partial inversion sweep + INV-1/2/3 lint
Implements Phase 6.7 deliverable per spec §10 (line 2391-2403):
Prompt edits per §6.2 sweep table:
- synthesis_agent.md line 164: remove "Cross-model audit follows ..."
sentence (Clause 2(b)+(d) violation); append canonical Clause 1 line
bullet to PATTERN PROTECTION block.
- research_architect_agent.md line 190: remove "Cross-model audit covers
these via dimension §3.5 ..." sentence (Clause 2(b)+(d) violation);
append canonical Clause 1 line.
- report_compiler_agent.md line 172: remove "Cross-model audit covers
these via dimension §3.7 ..." sentence; merge prior line 177 (trim
"The orchestrator runs codex audit afterward" tail) and line 178
("Output metadata must not claim audit-passed state") into the single
canonical Clause 1 line bullet.
Manifest (new): scripts/v3_6_7_inversion_manifest.json
- Three-file scope per §6.3; locks the v3.6.7 sweep boundary so
widening to a fourth file requires explicit §9 L2 resolution.
Lint extension: scripts/check_v3_6_7_pattern_protection.py
- INV-1: canonical Clause 1 line appears exactly once in each manifest
file's PATTERN PROTECTION block (presence + uniqueness).
- INV-2: zero hits across four Clause 2 disclosure regex patterns
(a) the orchestrator + audit, (b) cross-model audit follows/covers
+ codex_audit_multifile_template, (c) audit afterwards/will be run/
is dispatched, (d) downstream audit / this output is/will be audited.
All compiled with re.IGNORECASE per §6.3.
- INV-3: scans deep-research/agents/ + academic-pipeline/agents/ for
the canonical line; any hit outside the manifest fails (defends
against accidental sweep widening, guards §9 L2 deferred question).
- C3 regex consolidation: prior C1-C3 had two separate regexes for
(anti-fake-audit pair) and (output-metadata audit-passed prohibition)
bullets. Phase 6.7 merges them into a single whole-line regex matching
the canonical Clause 1 line so all three prohibition tokens
(DO NOT × 2 + must not) sit inside the matched span — the negation
post-filter no longer flags a sibling prohibition as a weakener
(B2 R3-001 span-restricted exemption).
Tests: scripts/test_check_v3_6_7_pattern_protection.py (+12 tests)
- INV-1 negative × 4: canonical line deletion (synthesis / architect /
compiler) + duplication (synthesis).
- INV-2 negative × 5: inject one canonical violation phrase per pattern
(a)/(b)/(c) and two for (d)'s alternation.
- INV-3 negative × 3: canonical line in non-manifest agent file
(bibliography_agent), manifest shrunk to two files, manifest extra
entry pointing to a file without the canonical line.
- Removed obsolete R3MutationTests.test_r3_001_orchestrator_does_not_run_fails
whose mutation source ("The orchestrator runs codex audit afterward.")
no longer exists post-sweep.
Verification gate per spec §10 line 2403:
- check_v3_6_7_pattern_protection.py: 12/12 passed (9 existing checks +
INV-1/2/3 aggregated)
- test suite: 40/40 tests green (28 existing - 1 obsolete + 13 new INV tests
including BaselineTest)
Phase 6.6 PR #65 was shipped standalone; Phase 6.7 follows as a separate
PR per spec §10 line 2401's bundling recommendation deferred (Phase 6.6
shipped first due to budget reconciliation patch in PR #64).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(v3.6.7 Phase 6.7 tests): update C3 audit-passed deletion mutation source post-canonical-line merge
Phase 6.7 merged line 178 ("Output metadata must not claim audit-passed
state.") into the canonical Clause 1 line bullet. The standalone bullet
form (preceded by `\n- `) no longer exists, so the prior
test_c3_audit_passed_sentence_deleted_fails mutation source string is
not found and the test errors out. Update the mutation to delete just
the audit-passed segment from within the merged canonical line bullet;
the assertion (lint must fail) is unchanged.
Verified: 40/40 tests pass after this fix.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(v3.6.7 Phase 6.7 R1): close 3 codex P2 INV bypass findings
Codex R1 review (model=gpt-5.5 + xhigh, --base main) surfaced three P2
findings against the initial INV-1/INV-2/INV-3 implementation. All three
allowed full lint PASS while the spec §6.3 invariant was violated.
R1-001 P2 — INV-2 wrapped disclosure bypass
- Pre-fix: 4 INV-2 patterns compiled with `re.IGNORECASE` only. `.*`
did not cross newlines, so a Markdown soft-wrap of a forbidden Clause
2 sentence (e.g. "the orchestrator" on one line, "audit" on the
next) reported PASS despite the disclosure being intact.
- Fix: compile all four INV-2 patterns with `re.IGNORECASE | re.DOTALL`
so `.` crosses newlines.
R1-002 P2 — INV-1 canonical-with-tail-weakener bypass
- Pre-fix: CANONICAL_CLAUSE_1_RE ended at `state\b`, so an agent prompt
could keep the canonical bullet's three sentences yet append a tail
weakener (` if feasible.`, `; this is recommended.`) and INV-1 still
matched the prefix. The spec §6.3 INV-1 rule requires the bullet
text to match verbatim, which means anchored to the sentence end.
- Fix: re-compile with `re.MULTILINE` and end the pattern at
`state\.\s*$` so the third sentence must be the bullet's terminal
content. Apply the parallel `state\.(?=\s|\Z)` anchor to the C3
whole-line regex inside the C1-C3 Check (defense in depth — the
pre-existing `_ALWAYS_NEGATION_PATTERNS` already lists `if feasible`
/ `when possible` / `where feasible` etc., but the regex anchor
closes the gap before negation post-filter is even consulted).
R1-003 P2 — Manifest copy-paste widening attack
- Pre-fix: `_load_inversion_manifest()` only validated that `scope ==
"v3.6.7-only"` and `files` was a list of strings. An attacker (or
well-intentioned editor) could append a fourth file to the manifest
AND copy the canonical bullet into that file's PATTERN PROTECTION
block. INV-1 then passed for all four files (canonical present
everywhere). INV-3 silently skipped the new file because it was now
in `manifest_set`. End result: full lint PASS, sweep silently
widened, spec §9 L2 deferred question marked decided without
resolution.
- Fix: introduce module-level `EXPECTED_MANIFEST_FILES` tuple frozen at
the v3.6.7 three-file scope. `_load_inversion_manifest()` now
validates `set(files) == set(EXPECTED_MANIFEST_FILES)` (exact match,
no superset / no drift) AND uniqueness (`len(files) ==
len(set(files))`). Per spec §6.3 line 1807, future v3.6.8+ widening
must land its own version-tagged manifest with its own scope tag,
not retroactively edit v3.6.7's manifest.
Tests added (4): each closure pair has at least one mutation regression
test in CodexR1MutationTests covering the bypass codex demonstrated:
- test_r1_p2_inv2_wrapped_disclosure_fails (R1-001)
- test_r1_p2_inv1_canonical_with_tail_weakener_fails (R1-002)
- test_r1_p2_manifest_widening_with_canonical_copy_fails (R1-003)
- test_r1_p2_manifest_duplicate_entry_fails (R1-003 defense in depth)
Verified: 44/44 tests pass (40 prior + 4 new R1 tests). 12/12 lint
checks pass on clean working tree.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(v3.6.7 Phase 6.7 R2): close 2 codex P2 INV bullet-extraction findings
Codex R2 review (model=gpt-5.5 + xhigh, --base main, after R1 fixes
landed) surfaced two more P2 findings — both about the granularity
mismatch between the spec's per-bullet semantics and the regex's
substring/cross-bullet matching.
R2-001 P2 — INV-1 false negative on bullet-prefix weakener
- Pre-R2: CANONICAL_CLAUSE_1_RE was a regex search-anywhere with
re.MULTILINE + `\.\s*$`. A bullet of the form `- When feasible, DO
NOT simulate ...` carried the canonical sentences as a substring;
the regex still matched the suffix and INV-1 reported PASS. The
spec §6.3 INV-1 rule says "exactly one bullet whose text matches
the canonical Clause 1 line verbatim" — substring match is not
verbatim.
- Pre-R2 dual: the same anchor rejected harmless soft-wraps (e.g. a
Markdown reflow line break between `run` and `codex/external`).
- Fix: introduce `_iter_bullets()` helper that walks `^- ` markers,
collapses each bullet's whitespace runs (including newlines from
soft wraps) to single spaces, and yields normalized bullet text.
INV-1 now compares each bullet's normalized text byte-for-byte
against `CANONICAL_CLAUSE_1_TEXT`. Soft-wrap tolerance preserved;
prefix weakener rejected; CANONICAL_CLAUSE_1_RE retired.
R2-002 P2 — INV-2 false positive across bullets
- Pre-R2: INV-2(a) `\bthe orchestrator\b.*\baudit\b` (and INV-2(b))
compiled with re.IGNORECASE | re.DOTALL applied to raw block text.
The unbounded `.*` would match across bullet boundaries — a benign
`the orchestrator` mention in one bullet plus the canonical bullet's
`audit step` mention in another would false-positive even though
no single sentence said the orchestrator runs an audit.
- Fix: `_inv2_check_file` now iterates `_iter_bullets(block)` and
applies each pattern against one bullet's normalized text at a
time. The canonical Clause 1 bullet is skipped (it inherently
contains "audit step" / "audit-passed state" tokens but is not a
disclosure). Patterns now compile with re.IGNORECASE only — DOTALL
is unnecessary because soft-wrap tolerance comes from the
whitespace-normalization step.
R2-derived consistency: INV-3 also now operates at bullet
granularity. Scanning the whole file as bullet sequence eliminates
false positives where a non-manifest agent prompt happens to discuss
the canonical wording in prose (a heading or paragraph mention does
not count as the canonical bullet).
Tests added (4): each closure has at least one regression test in
CodexR2MutationTests, plus one positive test for the soft-wrap
tolerance side of R2-001 and one for the cross-bullet false-positive
side of R2-002. Defense-in-depth test confirms a real in-bullet
INV-2 violation still fails after the per-bullet refactor.
Verified: 48/48 tests pass (44 prior + 4 new R2 tests). 12/12 lint
checks pass on clean working tree.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(v3.6.7 Phase 6.7 R3): close codex P2 INV-2 prose-paragraph regression
Codex R3 review (model=gpt-5.5 + xhigh, --base main, after R2 fixes
landed) surfaced one P2 — the R2 per-bullet refactor of INV-2 dropped
coverage of the intro paragraph, which is exactly where the Phase 6.7
sweep removed Clause 2 disclosures.
R3-001 P2 — INV-2 misses non-bullet prose disclosures
- Pre-R3: `_inv2_check_file` iterated only bullets (`_iter_bullets`).
But the three sentences removed by the §6.2 sweep
(`Cross-model audit follows ... codex_audit_multifile_template.md`)
were intro-paragraph prose, not bullets. The original forbidden
pipeline leak could be re-added to the intro paragraph and lint
silently passed all 12 checks.
- Fix: introduce `_iter_block_segments(block)` helper that yields
`(offset, kind, normalized_text)` for every matched-content
segment — both `prose` paragraphs (intro paragraph; future inline
paragraphs) AND `bullet` items. INV-2 now iterates segments,
whitespace-normalizing each (preserving R2's soft-wrap tolerance
and bounded-`.*` invariant), and applies the four patterns against
one segment at a time.
Heading line `## PATTERN PROTECTION (v3.6.7)` is excluded — it is
content marker, not contract content. The canonical Clause 1 bullet
is still skipped (it inherently carries `audit step` /
`audit-passed state` tokens; it is the required prohibition, not a
disclosure).
Tests added (1): `test_r3_p2_inv2_intro_paragraph_disclosure_fails`
re-introduces the synthesis_agent intro paragraph's original
`Cross-model audit follows ... codex_audit_multifile_template.md`
sentence and asserts INV-2 catches it as a `prose` violation. The
diagnostic includes the segment kind for debuggability.
Verified: 49/49 tests pass. 12/12 lint checks pass on clean working
tree. Manual probe confirms R3 attack vector (re-add Clause 2 prose
to intro paragraph) now fails with "[INV-2(b)] ... Clause 2
violation in prose: ...".
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(v3.6.7 Phase 6.7 R4): close codex P2 INV-2 post-bullet prose regression
Codex R4 review (model=gpt-5.5 + xhigh, --base main, after R3 fixes
landed) surfaced one more P2 — R3's segmentation only walked prose
paragraphs in `block[:first_bullet]`, missing prose appended after
the canonical bullet.
R4-001 P2 — INV-2 misses post-bullet prose disclosures
- Pre-R4: `_iter_block_segments` extracted prose paragraphs from
`block[:first_bullet]` only (intro paragraph + paragraphs before
the first `- ` marker), then appended bullet items. Any prose
appended AFTER the bullet list — e.g. a trailing paragraph saying
"The orchestrator runs codex audit afterward." after the canonical
bullet — fell outside the segmentation window and silently passed
the four INV-2 patterns.
- Fix: rewrite `_iter_block_segments` to paragraph-split the ENTIRE
block (`re.split(r"\n\s*\n", block)`) and classify each non-empty
paragraph as either a bullet group (starts with `- `, walked via
`_iter_bullets`) or a prose paragraph. Bullet-vs-prose discrimination
is uniform across the whole block, so:
* intro paragraph → prose
* first bullet group → bullets (one or more)
* inserted paragraph between bullet groups → prose
* trailing paragraph after last bullet → prose
The promise is now: every non-heading-non-empty character in the
block lands in one segment of the segmentation, no carve-out.
Tests added (1): `test_r4_p2_inv2_post_bullet_prose_disclosure_fails`
appends "The orchestrator runs codex audit afterward." as a prose
paragraph immediately after the canonical bullet in synthesis_agent
and asserts lint catches it as a Clause 2 prose violation.
Verified: 50/50 tests pass. 12/12 lint checks pass on clean working
tree. Manual probe confirms R4 attack vector now fails with
"[INV-2(a)] ... Clause 2 violation in prose: 'The orchestrator runs
codex audit afterward.'".
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(v3.6.7 Phase 6.7 R5): close codex P2 C3 regex soft-wrap intolerance
Codex R5 review (model=gpt-5.5 + xhigh, --base main, after R4 fixes
landed) surfaced one P2 — the C3 Check regex still used literal
spaces inside sentences while INV-1 had been refactored to
whitespace-tolerant exact compare. CI failed on harmless Markdown
soft-wraps inside the canonical bullet.
R5-001 P2 — C3 regex rejects soft-wrapped canonical bullet
- Pre-R5: C3 regex used `\s+` only between sentences but literal
single spaces inside each sentence. A soft-wrap inside a sentence
(e.g. between `run` and `codex/external`) caused C3 to FAIL even
though INV-1's bullet-text whitespace normalization correctly
accepted it. Result: CI failed on benign Markdown reflow despite
the v3.6.7 contract not being violated.
- Fix: every inter-token space inside the C3 regex now accepts
`\s+`. Soft-wrap tolerance is now uniform across:
1. INV-1 (`_iter_bullets` whitespace-normalization)
2. C3 Check regex (this fix)
The `\.(?=\s|\Z)` trailing anchor (R1 closure) is preserved so a
tail weakener like ` if feasible.` is still rejected.
Tests added (1): `test_r5_p2_compiler_softwrap_canonical_passes`
mutates report_compiler's canonical bullet to wrap between `run`
and `codex/external` and asserts lint passes (rc=0). Mirror of R2's
synthesis-side soft-wrap positive test, now covering the C3 surface.
Verified: 51/51 tests pass. 12/12 lint checks pass on clean working
tree.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(v3.6.7 Phase 6.7 R6): close codex P2 INV-1 weakened-duplicate bypass
Codex R6 review (model=gpt-5.5 + xhigh, --base main, after R5 fixes
landed) surfaced one P2 — INV-1's "exactly one bullet equals canonical"
contract counted ONLY exact matches, leaving room for a duplicate
weakened variant alongside the exact canonical bullet.
R6-001 P2 — INV-1 ignores weakened duplicates
- Pre-R6: `_inv1_check_file` counted bullets whose normalized text
equaled CANONICAL_CLAUSE_1_TEXT and required count == 1. An attacker
could keep the exact canonical bullet AND add a second near-canonical
variant (`- When feasible, DO NOT simulate ...` / `... audit-passed
state if feasible.`); the exact-count stayed at 1, lint passed, and
the block was left with two contradictory bullets the agent might
internalize. The spec §6.3 INV-1 wording "exactly one bullet whose
text matches the canonical Clause 1 line verbatim" implicitly forbids
weakened duplicates.
- Fix: introduce `_is_clause_1_like` helper using fragment markers
(`do not simulate`, `do not claim to have run`, `audit-passed
state`) to identify any bullet that reads as a Clause 1 variant.
`_inv1_check_file` now collects two bullet sets:
* exact: bullets whose normalized text equals canonical
* weakened: Clause 1-like bullets that are NOT exact
Lint fails if `weakened` is non-empty (any near-duplicate present)
OR if `len(exact) != 1`. Diagnostic enumerates the offending
weakened bullets so the editor sees exactly which ones to fix.
The fragment markers are load-bearing pieces of the canonical
sentence — no other v3.6.7 PATTERN PROTECTION bullet legitimately
carries them, so the heuristic does not false-positive on the A1-A5 /
B1-B5 / C1-C2 obligation bullets.
Tests added (2): `test_r6_p2_inv1_weakened_duplicate_alongside_canonical_fails`
covers the prefix-weakener variant; `test_r6_p2_inv1_tail_weakened_duplicate_fails`
covers the tail-weakener variant (defense in depth).
Verified: 53/53 tests pass. 12/12 lint checks pass on clean working
tree. Manual probe confirms both R6 attack vectors now fail with
clear diagnostic.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(v3.6.7 Phase 6.7 R7): close codex P2 INV-3 weakened-Clause-1 scope-leak bypass
Codex R7 review (model=gpt-5.5 + xhigh, --base main, after R6 fixes
landed) surfaced one P2 — INV-3 had the same weakened-duplicate
asymmetry that R6 closed inside manifest files: INV-3 rejected only
exact canonical bullets in non-manifest prompts, so a near-canonical
bullet outside the manifest still widened the v3.6.7 prohibition
scope silently.
R7-001 P2 — INV-3 misses Clause 1-like bullets outside the manifest
- Pre-R7: `_inv3_check` checked `bt == CANONICAL_CLAUSE_1_TEXT` for
each bullet in non-manifest agent files. A near-canonical variant
(`- When feasible, DO NOT simulate ...`) was not equal-byte to
canonical, so INV-3 passed even though the same prohibition
vocabulary was being smuggled into a fourth file.
- Fix: replace exact equality with `_is_clause_1_like` (the helper
R6 added for INV-1's weakened-duplicate detection). The same
fragment markers (`do not simulate`, `do not claim to have run`,
`audit-passed state`) now flag any Clause 1-like bullet anywhere
in a non-manifest agent file. Diagnostic enumerates offending
bullets so the editor can identify exactly what to remove.
The asymmetry between INV-1 (R6) and INV-3 (R7) is now closed:
both use the same Clause 1-like heuristic, so neither path can be
bypassed by the weakened-duplicate attack class.
Tests added (1): `test_r7_p2_inv3_weakened_clause_1_in_non_manifest_fails`
appends a `When feasible, ...` near-canonical bullet to
bibliography_agent.md (not in manifest) and asserts INV-3 fails.
Verified: 54/54 tests pass. 12/12 lint checks pass on clean working
tree. Manual probe confirms R7 attack vector now fails with
"[INV-3] ... Offending bullet(s): ['When feasible, DO NOT simulate ...']".
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(v3.6.7 Phase 6.7 R8): close 2 codex P2 INV-3 over-broad / under-broad findings
Codex R8 review (model=gpt-5.5 + xhigh, --base main, after R7 fixes
landed) surfaced two P2 findings — a false-positive on generic
anti-fabrication guidance AND a false-negative on prose-form
canonical pasting.
R8-001 P2 — `_is_clause_1_like` over-broad on generic prohibition
- Pre-R8: any bullet containing `do not simulate` or `do not claim
to have run` was flagged Clause 1-like. These are common
anti-fabrication phrases used in many agent prompts. A legitimate
bibliography guidance bullet `- Do not simulate data or sources.`
would false-positive INV-3 and prevent ordinary anti-fabrication
policies from being added to non-manifest agents.
- Fix: split fragments into two tiers:
_CLAUSE_1_AUDIT_FRAGMENTS = ("audit step", "audit-passed state",
"codex/external review")
_CLAUSE_1_GENERIC_FRAGMENTS = ("do not simulate",
"do not claim to have run")
`_is_clause_1_like` now requires at least one audit-specific
fragment. Generic fragments alone no longer trip the check, so
unrelated anti-fabrication guidance can ride elsewhere.
R8-002 P2 — INV-3 misses prose-form canonical pasting
- Pre-R8: `_inv3_check` only walked `- ` bullets. A non-manifest
prompt that pasted the exact canonical sentence as a normal
paragraph (not a Markdown list item) silently passed lint, even
though the prohibition was widened.
- Fix: add a paragraph-level scan inside `_inv3_check`. For each
non-bullet, non-heading paragraph in a non-manifest agent file,
whitespace-normalize and compare against `CANONICAL_CLAUSE_1_TEXT`
byte-for-byte. Prose match uses exact equality (not the
Clause 1-like heuristic) so a *discussion* of the canonical
wording in prose (e.g. quoting it for context) only fails when
the line is actually re-introduced as contract content.
Diagnostic enumerates offenders separately as `bullet:` vs `prose:`
so the editor sees exactly which form to fix.
Tests added (2):
- `test_r8_p2_generic_do_not_simulate_in_non_manifest_passes`
injects `- Do not simulate data or sources.` into
bibliography_agent and asserts lint passes (no false positive).
- `test_r8_p2_inv3_canonical_as_prose_in_non_manifest_fails`
injects the canonical sentence as a prose paragraph (not a
bullet) into bibliography_agent and asserts lint fails with
`prose: ...` offender diagnostic.
Verified: 56/56 tests pass. 12/12 lint checks pass on clean working
tree. Two manual probes confirm both attack vectors land correctly.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(v3.6.7 Phase 6.7 R9): close 2 codex P2 INV-3 architectural rewind
Codex R9 review (model=gpt-5.5 + xhigh, --base main, after R8 fixes
landed) surfaced that R7+R8's extension of the Clause 1-like heuristic
to INV-3 was over-extension. Spec §6.3 INV-3 wording says "canonical
Clause 1 line found outside the manifest" — that means the actual
sentence, not Clause 1-like variants. Variants outside the manifest
are a v3.6.8+ concern, not a v3.6.7 INV-3 contract.
R9-001 P2 — INV-3 over-broad on audit-related bullets outside manifest
- Pre-R9: INV-3 applied `_is_clause_1_like` to every bullet in non-
manifest agents. A legitimate process-flow bullet like
`- Review each audit step before finalizing.` triggered the lint
even though it has no prohibition semantics. The heuristic was
designed for INV-1's manifest-internal weakened-duplicate detection
(where any `audit step` mention SHOULD equal canonical), not for
scope-widening detection in unrelated agents.
- Fix: INV-3 now matches bullets via byte-exact whitespace-normalized
equality with `CANONICAL_CLAUSE_1_TEXT`. The Clause 1-like heuristic
remains in `_is_clause_1_like` for INV-1's R6+R8 contracts.
R9-002 P2 — INV-3 prose scan missed canonical after heading with no blank line
- Pre-R9: prose scan used `re.split(r"\n\s*\n", text)` to extract
paragraphs and filtered out paragraphs starting with `## `. When
an editor pasted `## PATTERN PROTECTION (v3.6.7)\nDO NOT simulate
...` (heading immediately followed by canonical sentence with no
intervening blank line), the entire chunk was one paragraph that
started with `## ` and was filtered out — canonical sentence
silently slipped past INV-3.
- Fix: replace paragraph-split with line-level heading-strip plus
whitespace-collapse. All non-heading non-bullet lines join with
single spaces; the canonical sentence is detected as a substring.
Heading adjacency no longer bypasses the scan.
Test updates:
- Renamed `CodexR7MutationTests` → `CodexR7R9MutationTests` and
inverted the R7 test's expectation: a weakened Clause 1 variant
outside the manifest now PASSES (not fails). Documents the R7→R9
architectural rewind.
- Added `CodexR9MutationTests` with two regression tests covering
R9-001 (audit-step bullet not equal to canonical passes) and
R9-002 (canonical-after-heading-no-blank-line fails).
Verified: 57/57 tests pass. 12/12 lint checks pass on clean working
tree. Two manual probes confirm both R9 attack/non-attack vectors
land correctly.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
10 lines
347 B
JSON
10 lines
347 B
JSON
{
|
|
"scope": "v3.6.7-only",
|
|
"rationale_doc": "docs/design/2026-04-30-ars-v3.6.7-step-6-orchestrator-hooks-spec.md#6-partial-inversion-rule-downstream-agent-prompt-edits",
|
|
"files": [
|
|
"deep-research/agents/synthesis_agent.md",
|
|
"deep-research/agents/research_architect_agent.md",
|
|
"deep-research/agents/report_compiler_agent.md"
|
|
]
|
|
}
|