Commit Graph
9 Commits
Author SHA1 Message Date
Marius CiepluchandClaude Opus 5.5 af81bccc70 feat(ruleset): tag framework-specific knowledge as optional priors (decision-engine task 2)
ruleset/frameworks.toml lists 19 framework and library ids (wordpress, flask, django, express,
spring, jakarta-servlet, react, vue and 11 libraries), each with its languages, dependency
package names and a symbol lexicon used only by the lint and for stratification.

Every framework/library entry of section 2 is tagged `framework`/`library`, and mixed entries
are split so a tag covers a whole entry (split pieces keep the entry's id and flags, in place):
semantic facts 38 tagged entries (wordpress 6, django 6, flask 4, express 4, jakarta-servlet 3,
pyyaml 2, one each for spring, sqlalchemy, requests, httpx, lodash, node-http-clients,
escape-html, sanitize-html, dompurify, esapi, commons-text, react, vue); the dispatch fact
behind the hook-as-source path is wordpress; the PHP layout row is renamed php_layout and stays
untagged (a product filter). Quick rules: 9 tagged (wordpress 6, flask, pyyaml,
node-http-clients); php-unserialize is split into php-unserialize and php-maybe-unserialize;
the lint also caught WordPress escapers in exclusions and axios/yaml.load in mixed rules, so
those keep their ids as tagged rules and gain a `fallback_for` language-level rule (6) that is
active only when the prior is off.

load_facts and load_ruleset take priors ("all" by default -- today's scan --, "off", or a set
of ids). tests/test_semantic_priors.py: the lint (no untagged entry contains a lexicon symbol
of its language), "off" removes exactly the tagged entries and activates the fallbacks, split
entries keep their language-level calls. Rule and layout counts in three existing tests follow the split and the rename.

Unchanged defaults: test_benchmark_output_is_byte_identical_to_golden_baseline passes, and the
quick findings of all 15 benchmark manifests (full StaticFinding records) are byte-identical
before and after. priors=off on the same manifests: 61 -> 57 findings; the 4 lost are js-ssrf
(axios), php-wpdb-sql-composition, python-ssti and python yaml.load; 5 PHP and 1 Python finding
move to their fallback rule at the same location. Semantic calls with priors off: php 75/92,
python 32/77, javascript 42/70, java 24/41, c 27/27 (the engine-side effect needs Joern and was
not measured).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01EmM1j46qgKMh3zqD1QMwEo
2026-09-30 18:49:05 +02:00
Marius CiepluchandClaude Opus 5.5 d1896cb8e7 feat(learn): candidate feature schema and builders (decision-engine task 1)
learn/schema.py is the closed, typed allow-list of candidate features: 66 features over
11 instruments (language one-hot, quick rules with 23 mechanism buckets and a prior count,
engine, repo-facts, source span, entry-point distance, roles, delta, verify, agree, model
sinks), two profiles (static 57; plane adds verify, agree and model sinks for 66), schema_version and a feature-set digest.
No repository, path, file, function, rule or commit identity is a feature; site_match,
in_fix_range, fixed-pin alerts, case.json fields and costs are refused. Missing is not zero:
each record carries per-instrument state (ran | none | failed | not_applicable), and every
feature of an instrument that did not run is null.

learn/features.py builds records on the host (build_for_scan, whole repository or base..head
delta); plane/tasks/features.py builds them per case in a Run from the delivered artifacts,
dropping site_match and in_fix_range on read and ignoring fixed-pin alerts. The generator
adds a model-free `features` entry per case before `remember`, which stores the records as
`features` rows (re-validated). memory KINDS gains features, label, decision, experiment,
arm_outcome and experiment_result. The committed validation-46 manifests are regenerated
(entries appended; the first Run's entries are unchanged). The runner image must be rebuilt
and re-pinned before a Run executes the new task.

Proof on real artifacts (scratch store, not committed): the recorded validation-46 run gives
75 feature records over 15 cases (43 verify candidates plus vulnerable-pin alerts), each
case's vulnerable pin exported and read (0.5k-9k files); remember stored 75 features rows
beside 43 verdict, 84 alert, 61 unit_cost, 15 facts and 8 coverage rows.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01EmM1j46qgKMh3zqD1QMwEo
2026-09-30 18:38:04 +02:00
Marius CiepluchandClaude Opus 5.5 edcf145b00 spec(learned-decision-engine): tasks approved; tasks 1-4 first, harvest waits for budget
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01EmM1j46qgKMh3zqD1QMwEo
2026-09-30 18:14:53 +02:00
Marius CiepluchandClaude Opus 5.5 d7a572498d spec(learned-decision-engine): design approved; implementation plan for review
Assumed-benign pushes mined from non-security commits as a separate label source
(maintainer decision). Ten tasks in the design's commit order; the harvest,
exp-001 and the v3 check wait for budget go-ahead.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01EmM1j46qgKMh3zqD1QMwEo
2026-09-30 18:14:31 +02:00
Marius CiepluchandClaude Opus 5.5 f6f9591cd0 spec(learned-decision-engine): design for review
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01EmM1j46qgKMh3zqD1QMwEo
2026-09-30 18:13:27 +02:00
Marius CiepluchandClaude Opus 5.5 ca1449a0aa spec(learned-decision-engine): Req 8 -- no framework knowledge as a prerequisite
Maintainer: hard-coded application specifications are problematic; WordPress is
not the only PHP application, same for Python and JS. Language-level knowledge
stays; framework roles are inferred per repository; existing framework entries
become tagged optional priors kept only by A/B evidence; leave-one-framework-out
evaluation.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01EmM1j46qgKMh3zqD1QMwEo
2026-09-30 18:03:13 +02:00
Marius CiepluchandClaude Opus 5.5 1b291e81b7 spec(learned-decision-engine): Req 7 -- judged on unseen repositories as a repo safety net
Maintainer: the tool will never run against the test cases it is trained with;
its purpose is a repo safety net. Repository-grouped folds, repository-agnostic
features, BLOCK/ADVISORY operating points for changed code, out-of-repo
calibration, adaptation kept separate.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01EmM1j46qgKMh3zqD1QMwEo
2026-09-30 18:01:06 +02:00
Marius CiepluchandClaude Opus 5.5 0fad93fcc5 spec(learned-decision-engine): requirements approved
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01EmM1j46qgKMh3zqD1QMwEo
2026-09-30 17:59:40 +02:00
Marius CiepluchandClaude Opus 5.5 afde23d3cf spec(learned-decision-engine): brief and requirements for review
Maintainer direction: A/B testing to extrapolate detection instead of hard-coding
it, and a trained decision engine. Instruments become signal producers; labels
from ground truth with provenance; a simple calibrated engine with population
folds; experiments as plane Runs; extrapolation with intervals, checked once on
frozen v3; the engine is what scan/pre-push/plane report.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01EmM1j46qgKMh3zqD1QMwEo
2026-09-30 17:59:06 +02:00