chore(deps): bump github/codeql-action from 3 to 4#3
Closed
dependabot[bot] wants to merge 580 commits into
Closed
Conversation
…e evidence Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Refactor corpus verification from per-rule to per-cell aggregation so precision/recall metrics are computed at the (rule_id, taint_state) granularity required by conformance evidence. Add _get_floors() helper that derives precision and recall floors from the severity matrix, and _print_cell_stats() that groups output by rule showing each taint cell with floor comparison. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…dicts Adds --json flag to `corpus verify` that emits a structured assessment report (format_version, cells, summary, overall_verdict) suitable for downstream conformance-evidence consumers. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…mance.json Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
….json Replaces hardcoded [] with generated evidence. Checks tool_version and manifest_hash staleness. Reports absent file as a gap.
…gs for implemented rules Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…g, exec regression 1. Staleness check now validates commit_ref and corpus_hash alongside tool_version and manifest_hash 2. corpus verify --json no longer injects live timestamp — deterministic output per §10 property 5 3. corpus publish fails with exit 1 when corpus specimens have errors — no conformance file from partial evidence 4. exec/eval security test: dry-run warmup pre-caches all transitive imports before patching builtins (pre-existing failure fixed) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ort all 72 matrix cells 1. self_hosting_input_hash: documented that commit_ref covers source staleness; the hash binds corpus publish's evidence chain, not scan-time re-validation (can't recompute without re-running engine) 2. JSON report now iterates all SEVERITY_MATRIX cells (72), not just cells with specimens — NO_DATA cells are visible instead of silently missing from the assessment artefact Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replaces documentation-only comment with actual validation. Enumerates src/wardline/**/*.py and computes inputHash using the same §10.1 algorithm. Catches source changes even without git (dirty tree, non-git environments). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adversarial corpus (27 new specimens): - 9 AFP specimens: one per PY-WL-001–009, testing scanner precision (or-fallback, 2-arg getattr, UPPER_CASE constant, immediate reraise, assignment body, non-audit logger, AST dispatch, has-rejection, shape-before-semantic) - 9 AFN specimens: one per rule, testing scanner recall through evasion (chained .get, 3-arg getattr, nested-in, conditional reraise, ellipsis body, audit-in-broad-handler, type() compare, no-rejection, noop-shape-check) - 1 suppression_interaction specimen (default-mismatch) + 2 existing tagged - 8 taint-flow specimens (boundary, validated, two-hop, shape-only, container-merge, join-semantics, governed-overlay, ungoverned-overlay) Conformance gate (corpus_cmds.py): - Replace hardcoded adversarial gap with per-rule AFP/AFN floor check against PY-WL-* rules from SARIF implementedRules - Aggregate floors for suppression_interaction (3) and taint_flow (8) - Track category + rule from specimen YAML during publish Bug fixes: - Fix 8 PY-WL-005 specimen sha256 hashes (YAML double-quote escaping) - Fix ADV-014 specimen (hasattr fires at all taint states, was wrongly TN) - Fix scan.py logging handler leak causing test ordering failure (_setup_logging now registers teardown via click context callback) Tests: - test_publish_adversarial_gap_removed_when_floor_met - test_publish_adversarial_gap_remains_when_rule_missing_afp Result: corpus verify 72/72 PASS, adversarial gap removed from conformance Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Reviewed all 17 PY-WL-004 self-hosting findings. 7 had genuinely too-broad `except Exception:` that could be narrowed to specific types: - corpus_cmds.py:201 — rule visitor: (AttributeError, KeyError, TypeError, ValueError) - exception_cmds.py:699 — taint assignment: add OSError to AST-processing errors - exception_cmds.py:713 — L3 propagation: narrow to AST-processing errors - explain_cmd.py:292 — exception register load: (OSError, ValueError) - explain_cmd.py:557 — fingerprint baseline parse: (OSError, ValueError, KeyError, JSONDecodeError) - regime_cmd.py:378 — manifest load: replace redundant Exception with OSError - scan.py:910 — config load: narrow to OSError (ScannerConfigError already caught above) 10 remaining are intentional resilience patterns (scanner engine, runtime enforcement callback, CLI validation checks) that will be documented as exceptions. Self-hosting findings: 463 → 456 (-7) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ception matching Exception register (wardline.exceptions.json): - 9 PY-WL-004 entries: intentional scanner resilience (engine pipeline degradation, CLI fallbacks, callback isolation, metrics fallback) - 17 PY-WL-005 entries: intentional silent handlers (Path.relative_to() control flow, ISO date parse fallbacks, batch file-skip, git fallback) - All reviewed, categorized, with specific rationale per handler Bug fixes: - Fix apply_exceptions path matching: resolve project_root before relative_to() so absolute file_paths match exception locations - Fix silent skip of malformed expiry dates in apply_exceptions: now logs warning before skipping - Add last_batch_refresh to exceptions schema so refresh metadata doesn't cause schema validation failure Self-hosting: 487 total, 32 excepted, 455 unexcepted (was 456) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Root cause: resolve_module_default() compared absolute scan file paths against relative manifest entry paths using PurePath.relative_to(), which always failed. Every function fell back to UNKNOWN_RAW regardless of wardline.yaml module_tiers declarations. Fix: add project_root parameter to resolve_module_default() and assign_function_taints(), threaded from ScanEngine through scan CLI. Entry paths are resolved against project_root before comparison. This affects all self-hosting scan results — findings now have correct taint states (AUDIT_TRAIL, PIPELINE, SHAPE_VALIDATED, EXTERNAL_RAW) instead of all-UNKNOWN_RAW, which changes their severity via the severity matrix. Also fixes: - exceptions.schema.json: add last_batch_refresh to allowed properties - exceptions.py: resolve project_root in apply_exceptions path matching Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…-hosting gate Taint assignment fix propagated to all callers: - exception_cmds.py: pass project_root to assign_function_taints - explain_cmd.py: pass project_root to resolve_module_default - Migrated 20 exceptions from UNKNOWN_RAW to correct taint states Self-hosting gate now excludes SUPPRESS-severity findings: - SUPPRESS means the severity matrix declares the finding silent at that taint state — not a violation requiring an exception - Added suppressed_cell_findings diagnostic counter to conformance output for tool-quality visibility - 15 PY-WL-007 findings at EXTERNAL_RAW are now correctly excluded Self-hosting: 440 unexcepted (was 455), 15 SUPPRESS excluded Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ADR-001: Rename taint states AUDIT_TRAIL/PIPELINE/SHAPE_VALIDATED to
STRICT/ASSURED/GUARDED. Keep EXTERNAL_RAW, UNKNOWN_RAW, MIXED_RAW
where RAW has clear semantic meaning. Eliminates the §5.1 defensive
NOTE ("don't read the name literally").
ADR-002: Rename tier-source decorators @audit_writer/@audit_critical/
@tier1_read/@authoritative_construction to @strict_writer/
@integrity_critical/@strict_read/@strict_construction. Validation
decorators (@validates_shape etc.) unchanged.
Both proposed for review board sign-off before implementation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
STRICT → INTEGRAL for T1 taint state. INTEGRAL is an adjective like ASSURED/GUARDED/UNTRUSTED, maintaining grammatical parallelism. Decorator prefixes: - Group 1 (data flow): integral_ (adjective, matches taint state) - Group 2 (consequence): integrity_ (noun, names the stake) Also incorporates review feedback: - Fixed TaintState enum count (5 renames, not 8) - Added spec Group 2 "Audit Primacy" rename to implementation notes - Added spec document updates (§5.1, §4.1, §1.1) to migration strategy - Documented INTEGRAL vs STRICT vs INTEGRITY trade-off Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- ADR-001: sharpen INTEGRAL rationale with concrete examples - ADR-001: add wardline.yaml tier definition IDs to blast radius - ADR-001: add spec Group 2 rename to migration steps (cross-ref ADR-002) - ADR-002: no changes needed (points 2 and 4 already addressed) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The severity matrix now encodes a core principle: rules protect the integrity of high-tier code paths, not the hygiene of low-tier code. The language permits .get(), getattr(), hasattr() for valid reasons. The tier system carves out code paths where those patterns are not permitted — because fabricated defaults in authoritative code undermine the guarantees that tier exists to provide. Matrix changes (3 rules x 8 taint states = 24 cells, 18 changed): PY-WL-001 (dict.get with default): T1: ERROR/UNCONDITIONAL (no change — trust model integrity) T2: ERROR/STANDARD (no change — validated data shouldn't need defaults) T3: WARNING/RELAXED (was ERROR — flag for review, don't block) T4: SUPPRESS (was ERROR — boundary code legitimately uses .get()) PY-WL-002 (getattr with default): T1/T2: ERROR (no change) T3: WARNING/RELAXED (was ERROR) T4: WARNING/RELAXED (not SUPPRESS — falsy-substitution risk in obj.attr-or-default) PY-WL-003 (existence-checking as structural gate): T1/T2: ERROR (no change — validated data should have known structure) T3: ERROR/STANDARD (was UNCONDITIONAL — exceptions now possible) T4: SUPPRESS (was ERROR — existence-checking IS the validation mechanism) Self-hosting gate updated: - Only ERROR findings block the gate (not WARNING) - WARNING tracked as separate counter (visible, non-blocking) - Creates economic incentive: promoting data to higher tier removes findings Impact: 440 gate-blocking → 178 ERROR + 42 WARNING + 232 SUPPRESS Panel review: 8-agent expert panel confirmed recalibration (ADR pending) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The framework matrix now reflects the tier boundary principle: rules
protect the integrity of high-tier code paths, not the hygiene of
low-tier code. T4 is the sandbox, not the vault.
WL-001 (member access with fallback default):
T3: E/St → W/R (flag for review, don't block)
T4: E/St → Su/T (boundary code legitimately uses .get())
UNKNOWN_RAW, MIXED_RAW: E/St → Su/T
WL-002 (existence-checking as structural gate):
T3: E/U → E/St (was UNCONDITIONAL, now exceptionable)
T4: E/St → Su/T (existence-checking IS the validation mechanism)
UNKNOWN_RAW, MIXED_RAW: E/St → Su/T
Updated spec sections:
§7.2.1: Removed "not to weaken WL-001 at EXTERNAL_RAW" — replaced
with T4-as-developer-freedom-zone rationale
§7.3: Framework matrix cells updated
§7.4(a): Rewritten — enforcement at boundary crossing, not at T4 access
§7.4(b): Rewritten — SUPPRESS at T4 for existence-checking
§7.5: Added "tier boundary principle" as first derivation principle
Footnotes: UNCONDITIONAL count updated (26 → 23)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The Python binding section now includes the full 72-cell matrix table matching the implementation in core/matrix.py. Documents the PY-WL-002 binding-level deviation: WARNING/RELAXED at T4 instead of SUPPRESS, because obj.attr-or-default has a falsy-substitution risk (replaces present-but-falsy values, not just missing attributes). This narrows relative to the framework's WL-001 SUPPRESS, which is permitted by §7.3. Replaces the "inherits without modification" paragraph that was no longer accurate after the framework matrix recalibration. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
PY-WL-003 ("existence-checking as structural gate") was firing on
set membership tests like `x in my_set` which are value classification,
not structural gating. `x in my_frozenset` has no Python alternative —
`in` is the only way to test set membership.
Added _collect_set_variable_names() pre-pass in visit_function that
tracks local names assigned from:
- Set literals: `s = {1, 2, 3}`
- Set/frozenset constructors: `s = set(items)`
- Set comprehensions: `s = {x for x in items}`
- Set operations: `s = a | b`, `s = a - b`
- Parameter annotations: `def f(s: set[str])`
Membership tests against tracked names are suppressed as value
classification, not structural gating.
Self-hosting impact: 178 → 117 gate-blocking ERROR findings (-61)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…d ops
Enhanced _collect_set_variable_names to detect sets built incrementally:
- s.add(x), s.discard(x), s.update(other) → receiver is a set
- s |= other, s -= other → augmented set operations
This catches the common pattern:
anchored = set()
for f in functions:
anchored.add(f)
if f in anchored: # now suppressed (value classification, not structural gate)
Self-hosting impact: 117 → 93 gate-blocking ERRORs (-24)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Added three more patterns to _collect_set_variable_names: 1. Loop variables from iterables that yield sets: `for scc in compute_sccs(graph)` → scc is a set 2. Method return values with set-suggesting names: `annotations = self._annotation_names()` → likely frozenset 3. Name-based heuristic for method calls ending in _names, _set, _keys, _ids (strong correlation with set/frozenset return types) Self-hosting impact: 93 → 68 gate-blocking ERRORs (-25) PY-WL-003 specifically: 40 → 25 (-15) Note: 12 test failures exist from concurrent agent's .get()→if/else rewrites in enforcement.py and models.py — not from this change. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The .get() → try/except rewrite replaced three inline .get() calls in the return statement with variable references (_allow_registry_mismatch, _allow_permissive_distribution, _strict_governance) but didn't define those variables. Added the try/except KeyError blocks. Fixes 12 test failures across test_models.py, test_regime.py, test_regime_cmd.py, and test_module_tiers_auditability.py. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…rprint bug
Code fixes (T1 AUDIT_TRAIL — UNCONDITIONAL):
- enforcement.py: replace getattr/hasattr/.get() with try/except in
stamp_tier, check_tier_boundary, check_subclass_tier_consistency,
_reset_enforcement_state
- decorators/_base.py: replace getattr with try/except in
wardline_decorator, get_wardline_attrs; add _safe_name helper
- runtime/base.py: replace getattr with try/except in
_check_decorated_methods, _validate_decorator_attr
- runtime/descriptors.py: replace hasattr with try/except in
AuthoritativeField.__get__
- core/taints.py: replace _JOIN_TABLE.get() with explicit if/else
in taint_join
Code fixes (T2 PIPELINE — dict key access):
- callgraph_propagation.py: convert dict .get()/.in checks to
try/except KeyError throughout propagate_callgraph_taints and
compute_sccs
- variable_level.py: convert dict .in checks to try/except in
_handle_if, _handle_for, _handle_while, _handle_try, _resolve_call
- callgraph.py: convert dict .in checks to try/except in
extract_call_edges
- coherence.py: convert dict .in checks to try/except in
check_tier_downgrades, check_tier_upgrade_without_evidence,
check_unmatched_contracts
Scanner fixes:
- py_wl_007.py: extend _is_ast_qualified_type to recognize _AST_*
module-level aliases (version-compatibility pattern)
- fingerprint.py: resolve project_root before .relative_to() — third
occurrence of the systemic unresolved Path(".") bug
Exception register:
- 39 PY-WL-007 exceptions with per-finding rationale (enforcement
mechanism, config parsing, AST value dispatch)
- 13 PY-WL-001 exceptions with per-finding rationale (manifest
baseline access, SARIF mapping tables, taint model fallbacks)
- Refreshed 16 stale exceptions after code changes
Findings: 440 ERROR → 26 ERROR (25 PY-WL-003 suppression gaps +
1 PY-WL-004 suppression gap, reported for rule fixes)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…l + manifest coverage PY-WL-003 suppression improvements: - Suppress "sub" in string_var (substring containment, not key existence) Detects variables with _lower, _name, _text, _str suffixes - Suppress x in self.attr (instance set/frozenset attributes used for classification, not dict key gating) PY-WL-005 matrix recalibration: - T3 (SHAPE_VALIDATED): E/St → W/St (flag for review, don't block) - T4 (EXTERNAL_RAW): E/St → W/R (boundary code may suppress parse errors) - Same tier principle: T4 is the sandbox, T1 is where you need surgical exception handling because you should understand your failure modes wardline.yaml manifest coverage: - Add catch-all src/wardline/scanner → SHAPE_VALIDATED for modules not explicitly listed (import_resolver, fingerprint, exceptions, _qualnames, _scope, rejection_path) - Add catch-all src/wardline/manifest → PIPELINE for modules not explicitly listed (scope, exceptions, resolve, regime) - Eliminates UNKNOWN_RAW fallback for covered modules Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…tionale Framework matrix WL-004: E/St at T3/T4 → W/St and W/R - T1: surgical exception handling required — every exception should be understood and handled specifically - T4: defensive suppression of unpredictable external failures is expected practice New §7.4(g) worked example: exception handling tier gradient - Explains why broad/silent catches are an integrity problem at T1 (you don't understand your failure modes) but expected practice at T4 (external systems throw unpredictable exceptions) - Clarifies that logging is not handling — logger.warning() in a broad catch is a confession, not a remedy - Documents the re-raise exemption distinction: `except: raise` is genuinely not swallowing; `except: log(); return fallback` is Updated WL-004 rule description to replace "nearly uniform across contexts" with tier-differentiated reasoning. Python binding PY-WL-005 matrix updated to match framework. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…WL-004) PY-WL-004 rationale (T1 broad exception handler on user callback): The previous implementation used `except Exception: logger.warning()` on the user-supplied on_violation callback. The spec (§7.3 WL-004) says T1 code should understand its failure modes — a warning log notes the failure but doesn't handle it. The exception is swallowed and execution continues as if the callback ran. The fix separates two failure modes: - TypeError (wrong callback signature): re-raised immediately as a configuration error. The caller registered a handler that doesn't match the documented (obj, expected_tier, actual_tier) contract. - All other exceptions: logged at ERROR (not WARNING) and recorded in _callback_failures list for programmatic observability. Execution continues so the caller can still raise its TierViolationError — the enforcement violation must not be masked by a callback bug. Note: PY-WL-004 still fires because the rule detects exception BREADTH (any `except Exception:`), not SILENCE (empty handler body). This is a rule implementation bug — the scanner implements WL-003 semantics (broad catch detection) under the PY-WL-004 rule ID, which the spec defines as WL-004 (silent catch detection). Filed as suppression gap. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
UNKNOWN_RAW is stricter than EXTERNAL_RAW across all rules because: 1. It masks ambiguity — code doesn't know if data is malformed external input or corrupted internal state 2. UNKNOWN_RAW can reach T1 via internal paths without crossing a declared validation boundary; EXTERNAL_RAW must traverse the boundary chain The stricter posture compensates for the shorter path to authoritative code. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move website source (homepage, getting-started, specification
landing, reference, guides, stylesheets, javascripts, assets,
mkdocs Material overrides) out of docs/ and the repo root into
a new site-src/ directory. Symlink docs/{spec,adr,audits,
verification,requirements} into site-src/ so mkdocs serves
them at unchanged URL paths.
docs/ now holds only authoritative source material.
site-src/ holds website source.
mkdocs.yml changes:
- Add docs_dir: site-src
- theme.custom_dir: overrides -> site-src/overrides
- Remove edit_uri (edit buttons temporarily disabled while
the edit_uri / symlink interaction is resolved in the
follow-up plan, post v1.0 cert)
No nav changes, no content edits, no deletions. URL paths,
rendered content, and the PDF build pipeline
(tools/pdf/build-spec.sh) are unchanged.
Plan: docs/superpowers/plans/2026-04-12-wardline-site-move.md
Follow-up (post-cert): docs/superpowers/plans/2026-04-12-wardline-site-restructure.md
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Introduced a new compliance ledger schema in JSON format to enforce the obligation record contract as per §15.1. - The schema includes properties for obligation records, evidence binding, and summary statistics, ensuring compliance with the specified requirements. - Added a working document outlining the roadmap to ship Wardline v1.0, detailing the current ledger state, obligations, and necessary steps for achieving full compliance. - The roadmap includes stages for evidence capture, BAR pipeline implementation, and graduation constraints, providing a clear path to release.
Tests encode the §6 join algebra at the L3 propagation level. Cross-classification callee combinations must produce MIXED_RAW. These fail against the current TRUST_RANK/max() implementation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Verifies propagation result is independent of callee iteration order. Passes on current code; guards the invariant after taint_join refactor. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Phase 1 external influence now uses taint_join() to combine callee taints per §6 join algebra. TRUST_RANK retained for floor clamps (ordering comparison, not taint combination). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
join(ASSURED, EXTERNAL_RAW) = MIXED_RAW per §6 cross-classification rule. MIXED_RAW (rank 7) exceeds the L1 floor (UNKNOWN_RAW rank 6), so the result is correctly MIXED_RAW, not UNKNOWN_RAW. Also updates test_cycle_converges: same cross-classification applies when UNKNOWN_RAW and EXTERNAL_RAW meet through the cycle. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Sort stdlib imports (dataclass before functools) - Remove unused TaintState runtime import (available via TYPE_CHECKING) - Combine nested if statements (SIM102) - Use ternary for simple if/else assignment (SIM108) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Each surviving TRUST_RANK usage in the propagation module now carries a comment explaining it is an ordering comparison, not a taint combination. Supports audit defensibility per IRAP reviewer guidance. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
L3 callgraph propagation now uses taint_join() for callee combination. Evidence bound to TestCrossClassificationJoin (7 tests) and test_join_commutativity_at_propagation_level (property test). Pending BAR pipeline review for verified state. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The taint_join refactor left SCC propagation sensitive to worklist processing order. In recursive SCCs with cross-classification L1 taints, early processing could "wash" a callee's classification (e.g., INTEGRAL→ASSURED), hiding the cross-classification from later SCC members. Fix: for non-anchored SCC-internal callees in Phase 2, read taint_join(taint_map[c], current[c]) instead of bare current[c]. This preserves each callee's L1 classification through iterations, ensuring cross-classification detection is order-independent. Also fixes the commutativity property test: the previous version used set(sorted(v, reverse=True)) which produces the same set and never varied iteration order. Replaced with name-permutation that actually changes min(worklist) pick sequence. Adds regression test: test_scc_cross_classification_order_independent runs the same graph with swapped node names and verifies identical results. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The SCC L1 preservation (taint_join(taint_map[c], current[c]) for SCC
callees) over-taints recursive shapes by re-injecting stale L1
classifications. Minimal repro: A(INTEGRAL)→{A, B(ASSURED)} resolves
to A=MIXED_RAW when the callee contract gives A=ASSURED.
Reverts the c-in-scc branch added in 85f5b59. The SCC worklist
order-dependence for cross-classification L1 taints is now documented
as a known limitation via xfail test rather than incorrectly "fixed"
with L1 re-injection.
Also fixes stale compliance evidence:
- Corrects test target from test_join_commutativity_at_propagation_level
to test_propagation_order_independent
- Notes the known SCC limitation in the obligation record
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ependence The previous SCC fix (85f5b59) re-injected L1 taints via taint_join(taint_map[c], current[c]) for all SCC callees, which over-tainted single-node SCCs and self-loops. Reverted in d63c729. Root cause: the worklist iteration with taint_join has non-monotone transfer functions on the partial-order lattice. When SCC members have cross-classification L1 taints (e.g., ASSURED + INTEGRAL), early worklist processing can laterally move a callee (INTEGRAL→ASSURED via floor clamp), hiding the cross-classification from later members. Fix: before the Phase 2 worklist, compute the taint_join of all non-anchored SCC members' L1 taints. If this join exceeds any member's current taint, pre-set them. This ensures cross-classification is visible before any worklist processing, without re-injecting L1 into callee reads or over-tainting single-node SCCs. - Multi-member cross-class SCC: both orderings → MIXED_RAW ✓ - Single-node SCC with external callee: A=ASSURED (not MIXED_RAW) ✓ - Same-classification SCC: no pre-setting, unchanged behavior ✓ Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…t-processing - Implement unit tests for BAR CLI commands including status, review, and rerun functionalities. - Create tests for compliance ledger schema validation against JSON schema. - Introduce a post-processing script for Typst transformations in the PDF pipeline. - Define table column width profiles for various tables used in the Wardline PDF pipeline.
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3 to 4. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](github/codeql-action@v3...v4) --- updated-dependencies: - dependency-name: github/codeql-action dependency-version: '4' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com>
Contributor
Author
|
OK, I won't notify you again about this release, but will get in touch when a new version is available. If you'd rather skip all updates until the next major or minor version, let me know by commenting If you change your mind, just re-open this PR and I'll resolve any conflicts on it. |
tachyon-beep
pushed a commit
that referenced
this pull request
Jun 2, 2026
…m improvements.md Implements the useful items from docs/notes/improvements.md: PY-WL-111 — a @trust_boundary whose only rejection path is `assert` (CWE-617). Stripped under `python -O`, so the validation silently vanishes in production. Declaration-gated, ERROR. Teaches the shared `has_rejection_path` helper to count `assert` so PY-WL-102 and PY-WL-111 partition cleanly (102 = cannot reject at all; 111 = appears to reject but only via an -O-stripped guard; never both). Test guards (no behavior change): - #1 rule-examples meta-test: every builtin rule's examples_violation fire it / examples_clean don't, and every rule ships both. Caught + fixed rotted PY-WL-101 examples (referenced an undefined helper → unprovable → never fired). - #2 RAW_ZONE ↔ TRUST_RANK consistency pin. - #5 least_trusted idempotence + associativity (exhaustive 8^3). - #4 fingerprint-stability: pins the REAL anchor-line contract (anchor-preserving edits stay byte-identical; a line shift changes it by design — line_start is a fingerprint input, so making it line-independent would itself be breaking). - #3 CLI ↔ MCP finding-parity differential, guarding the "identical by construction" tenet via the real _scan handler. Docs: rules.md, CLAUDE.md/AGENTS.md rule tables brought current (105–110 were never added after T1.5) + 111; CHANGELOG [Unreleased]; improvements.md status (#6 mutation testing deferred; soundness/FN closures = separate batch). Gate: 1807 passed, coverage 96.22%, ruff + mypy clean, mkdocs --strict, dogfood finding-clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
tachyon-beep
pushed a commit
that referenced
this pull request
Jun 2, 2026
…(WS-A2) The defining federated triage move: turn a single true-positive into tracked work, keyed on Wardline's stable fingerprint, over HTTP-via-urllib only. - core/filigree_issue.FiligreeIssueFiler — sibling of FiligreeEmitter: injectable transport, stdlib urllib, fail-soft charter (404 -> not_found; 5xx/URLError -> soft; other 4xx -> loud FiligreeEmitError). Derives the promote route from the configured Loom scan-results URL. - MCP `file_finding` tool + CLI `wardline file-finding` verb, both delegating to the one filer (identical by construction). CLI catches WardlineError -> clean `error:` + exit 2 (distinct from soft-unreachable exit 1). - Emission now sets `mark_unseen=True` on NON-EMPTY scans (Filigree rejects mark_unseen on an empty batch), so a fixed finding enters Filigree's per-(file,scan_source) `unseen_in_latest` state and a regressed one reopens its linked issue on the next scan. Finding gains NO issue_id — the fingerprint<->issue link stays in the reconciliation layer. - Opt-in `filigree_e2e` live oracle (skips until the promote route is up). Honest scope: reopen-on-regress is immediate; issue close-on-fixed is gated on Filigree's clean-stale sweep, which Wardline does not call. Closing that gap is Filigree ask #3 (symmetric close cascade in process_scan_results) — docs/superpowers/specs/2026-06-02-filigree-ask-close-cascade-on-ingest.md; needs no further Wardline change. Spec: docs/superpowers/specs/2026-06-02-wardline-frictionless-agent-surface-spec.md §4 A2. Plan: docs/superpowers/plans/2026-06-02-wardline-ws-a2-file-finding.md. Gate green: 1870 passed, ruff/mypy clean, dogfood exit 0. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
tachyon-beep
pushed a commit
that referenced
this pull request
Jun 4, 2026
Extend the opt-in filigree_e2e live oracle (wardline-7a56cd1b83) with the WS-A2 close-on-fixed lifecycle: file finding -> issue opens; fix the code + re-scan -> issue closes (driven by mark_unseen + the full scanned_paths set, no clean-stale sweep); regress -> issue reopens. Asserted over the core emit path, the real `wardline scan --filigree-url` CLI, and the MCP scan tool against a live Filigree running the close cascade. Skips cleanly until WARDLINE_FILIGREE_URL points at a cascade-capable Filigree. Also lands the close-on-fixed gap-closure plan and the v2 ask brief that drove the Filigree-side (ask #3 + #3b) work. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This was referenced Jun 6, 2026
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bumps github/codeql-action from 3 to 4.
Release notes
Sourced from github/codeql-action's releases.
... (truncated)
Changelog
Sourced from github/codeql-action's changelog.
... (truncated)
Commits
5cc552fMerge pull request #3768 from github/dependabot/npm_and_yarn/npm-minor-3536e7...6b1a9f2Merge branch 'main' into dependabot/npm_and_yarn/npm-minor-3536e7c6f09d3ec57Merge pull request #3770 from github/dependabot/github_actions/dot-github/wor...3ff82aaMerge pull request #3575 from github/mbg/ts/sync-checks4bdd4e7Merge pull request #3554 from github/sam-robson/overlay-include-diff23a0098fix: improve error handling and logging for diff range path resolutionea7b090Rebuilda663d01Bump ruby/setup-rubyb659882Bump the npm-minor group with 5 updatesd5bb39frefactor: single source of truth for getDiffRangesJsonFilePath and simplified...You can trigger a rebase of this PR by commenting
@dependabot rebase.Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR:
@dependabot rebasewill rebase this PR@dependabot recreatewill recreate this PR, overwriting any edits that have been made to it@dependabot show <dependency name> ignore conditionswill show all of the ignore conditions of the specified dependency@dependabot ignore this major versionwill close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)@dependabot ignore this minor versionwill close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)@dependabot ignore this dependencywill close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)