Skip to content

Commit b8f52c2

Browse files
authored
Merge pull request #61 from rsolerortuno/agent/codex/506-dependency-integration-gate
Gate optional dependency-aware integration
2 parents 2410cf1 + 9c2cc37 commit b8f52c2

10 files changed

Lines changed: 677 additions & 0 deletions
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# v0.5.0 dependency integration current-state audit
2+
3+
Production scoring starts in `targetintel/scoring.py` (`score_all_profiles`)
4+
and uses the three `configs/scoring_*.yaml` profiles. Production intent ranking
5+
starts in `targetintel/intent_ranking.py` (`build_intent_rankings` and
6+
`add_intent_ranks`); it adds separate rank columns to a dataframe and remains
7+
the default path. Selected-state values are carried by baseline artifacts but
8+
are not a registration mechanism. The global CLI (`targetintel/cli.py`) calls
9+
the deterministic pipeline; it has no optional dependency-profile selector.
10+
11+
Issue 505 is isolated in `targetintel/functional_dependency/depmap_benchmark.py`.
12+
It consumes explicit frozen universe/profile/baseline/policy inputs and writes
13+
`dependency_benchmark_manifest.json`, metrics, bounded-overlay diagnostics, and
14+
`integration_evidence.json`. Its manifest is analysis-only and has status
15+
`human_review_required`; its overlay ranks are separate diagnostic fields.
16+
17+
There was no profile registry, auto-discovery, environment-variable enablement,
18+
or global optional-profile selection mechanism. A file could not become the
19+
production default through presence alone. The baseline benchmark loader reads
20+
a TSV and calculates a fingerprint; it does not mutate the source file.
21+
22+
The canonical Issue 506 boundary is the new isolated
23+
`targetintel.functional_dependency.dependency_integration` module. It verifies
24+
the Issue 505 manifest and its profile/universe/baseline/policy identities,
25+
uses an explicit context and evidence scope, builds a separately stored
26+
candidate overlay, and proves baseline byte/fingerprint preservation. The
27+
candidate retains baseline ranking/profile provenance and is selectable only by
28+
a future explicit caller plus separate approved human authorization. It is not
29+
connected to production scoring/ranking or the global CLI.
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# v0.5.0 dependency integration gate
2+
3+
Issue 506 is an offline, isolated decision gate between the Issue 505
4+
analysis-only dependency benchmark and any future optional profile. Its
5+
canonical boundary is `targetintel.functional_dependency.dependency_integration`.
6+
It reads only an explicit baseline TSV and Issue 505 artifacts; it does not
7+
import production scoring, intent ranking, role classification, feature
8+
construction, modality, CLI, reports, LLMs, or network code.
9+
10+
The controlled evidence scopes are `synthetic_fixture`, `local_real_data`,
11+
and `externally_validated_real_data`. Scope is a required caller argument and
12+
enters the decision identity. Synthetic fixture scope always produces
13+
`blocked_fixture_evidence`; a real-data label alone does not establish
14+
scientific adequacy.
15+
16+
The controlled states are `blocked_fixture_evidence`,
17+
`blocked_insufficient_evidence`, `blocked_incompatible_inputs`,
18+
`blocked_policy_failure`, `eligible_for_human_activation`,
19+
`human_review_required`, and `explicitly_rejected`. Unknown values fail closed.
20+
Eligibility is not activation.
21+
22+
`DependencyIntegrationPolicy` is immutable and content-addressed. It fixes
23+
coverage, holdout, eligible-count, Recall@K, negative-control, bounded-overlay
24+
stability, displacement, band-violation, ablation, and missing-profile
25+
thresholds; construction method; fallback; opt-in; human-approval requirement;
26+
and limitations. It rejects target-specific settings, tuning, callbacks,
27+
expressions, credentials, and hidden reasoning. Results never enter policy
28+
identity.
29+
30+
The gate verifies frozen-universe, benchmark-universe, profile-run, baseline
31+
ranking and SHA-256 fingerprint, Issue 505 policy, and context identities.
32+
Missing or conflicting identities fail closed and retain exact reasons. Every
33+
criterion has an ID, source artifact/field, observed value, operator,
34+
threshold, pass/fail/unavailable result, and limitations. Unavailable is never
35+
pass; no aggregate score exists.
36+
37+
The deterministic candidate is named
38+
`dependency_aware_melanoma_anti_pd1_candidate_v1`. It is context-bound,
39+
analysis-only, non-default, and contains no benchmark or holdout labels,
40+
target-specific weights, credentials, or clinical-validation claim. Its
41+
bounded overlay retains baseline score and rank separately, only reorders
42+
eligible rows inside fixed baseline bands, and preserves missing-profile order.
43+
44+
The baseline TSV bytes and fingerprint are checked before and after evaluation.
45+
The gate emits separate proof that scores/ranks are retained and that production
46+
configuration/defaults remain untouched; it cannot register a global profile.
47+
`select_dependency_profile` returns baseline when selection is absent, rejects
48+
unknown or blocked selection, and requires a future approved authorization even
49+
after eligibility.
50+
51+
`DependencyProfileAuthorization` is a future contract only. It requires the
52+
candidate, real-data benchmark, decision, context, reviewer reference, status,
53+
and limitations. Fixture authorization is rejected. Issue 506 emits no approved
54+
authorization.
55+
56+
The activation-readiness bundle is immutable and reports blocked, eligible for
57+
human review, or rejected. The bundled synthetic fixture is blocked, although
58+
it still emits an overlay for audit. Issue 507 must run the same gate after a
59+
pinned local real-data benchmark, inspect every failure/unavailable result, and
60+
obtain separate human authorization; it must not auto-enable the candidate.

‎examples/depmap/README.md‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,20 @@ python examples/depmap/run_dependency_benchmark.py \
6767
--policy tests/fixtures/depmap/benchmark/evaluation_policy.json \
6868
--output-dir /tmp/targetintel-dependency-benchmark
6969
```
70+
71+
## Dependency integration gate
72+
73+
Issue 506 consumes that benchmark only through an explicit, offline gate. It
74+
writes an analysis-only candidate overlay and never changes production scores,
75+
ranks, defaults, or CLI behavior. The synthetic fixture is always blocked;
76+
human authorization is not emitted.
77+
78+
```bash
79+
python examples/depmap/run_dependency_integration_gate.py \
80+
--benchmark-dir /tmp/targetintel-dependency-benchmark \
81+
--baseline-ranking tests/fixtures/depmap/benchmark/baseline_ranking.tsv \
82+
--policy tests/fixtures/depmap/integration/integration_policy.json \
83+
--context tests/fixtures/depmap/integration/context.json \
84+
--evidence-scope synthetic_fixture \
85+
--output-dir /tmp/targetintel-dependency-integration
86+
```
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#!/usr/bin/env python3
2+
"""Run the offline Issue 506 dependency-integration gate."""
3+
from __future__ import annotations
4+
import argparse
5+
import json
6+
from pathlib import Path
7+
import sys
8+
9+
PROJECT_ROOT = Path(__file__).resolve().parents[2]
10+
if str(PROJECT_ROOT) not in sys.path:
11+
sys.path.insert(0, str(PROJECT_ROOT))
12+
13+
from targetintel.functional_dependency import (
14+
DependencyIntegrationError, DependencyIntegrationPolicy,
15+
build_dependency_integration, write_dependency_integration_artifacts,
16+
)
17+
18+
def main() -> int:
19+
parser = argparse.ArgumentParser(description=__doc__)
20+
parser.add_argument("--benchmark-dir", required=True)
21+
parser.add_argument("--baseline-ranking", required=True)
22+
parser.add_argument("--policy", required=True)
23+
parser.add_argument("--context", required=True)
24+
parser.add_argument("--evidence-scope", required=True)
25+
parser.add_argument("--output-dir", required=True)
26+
args = parser.parse_args()
27+
try:
28+
policy = DependencyIntegrationPolicy.from_dict(json.loads(Path(args.policy).read_text(encoding="utf-8")))
29+
result = build_dependency_integration(Path(args.benchmark_dir).resolve(), Path(args.baseline_ranking).resolve(), policy, json.loads(Path(args.context).read_text(encoding="utf-8")), args.evidence_scope)
30+
write_dependency_integration_artifacts(Path(args.output_dir).resolve(), result)
31+
except (DependencyIntegrationError, ValueError) as error:
32+
parser.error(str(error))
33+
print(result["decision"]["decision_id"])
34+
return 0
35+
36+
if __name__ == "__main__":
37+
raise SystemExit(main())

‎targetintel/functional_dependency/__init__.py‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@
3131
DependencyBenchmarkPolicy, evaluate_dependency_benchmark,
3232
load_baseline_ranking, write_dependency_benchmark_artifacts,
3333
)
34+
from .dependency_integration import (
35+
DependencyAwareProfileCandidate, DependencyIntegrationError,
36+
DependencyIntegrationPolicy, DependencyProfileAuthorization,
37+
build_dependency_integration, select_dependency_profile,
38+
validate_evidence_scope, validate_integration_state,
39+
write_dependency_integration_artifacts,
40+
)
3441

3542
__all__ = [
3643
"DepMapFileManifest",
@@ -65,4 +72,13 @@
6572
"evaluate_dependency_benchmark",
6673
"load_baseline_ranking",
6774
"write_dependency_benchmark_artifacts",
75+
"DependencyAwareProfileCandidate",
76+
"DependencyIntegrationError",
77+
"DependencyIntegrationPolicy",
78+
"DependencyProfileAuthorization",
79+
"build_dependency_integration",
80+
"select_dependency_profile",
81+
"validate_evidence_scope",
82+
"validate_integration_state",
83+
"write_dependency_integration_artifacts",
6884
]

0 commit comments

Comments
 (0)