Repository navigation
Code Analysis Saved Language Questions
This follow-up extends single-entry question orientation to a captured .py or .java implementation file from matching Python/Java raw facts. It is a bounded source-reading capability: it reuses saved function ranges, file dependencies and current-source checks. It does not introduce Python/Java call analysis or extend the fresh JS/TS paired mode.
The public parent is #1229 at 3dda561d5db3323b00e8df20627ada96aec95900. That parent intentionally rejects these languages with task/entry-invalid; this was a coverage opportunity, not a defect in the existing JS/TS contract. Candidate 29f73e9c30ee72b3f085a2b13caedcaa50d1d4da is published as Draft #1234, the seventh layer of native stack #1221. No lower branch changed and nothing was merged.
A subsequent pandas selection study exercises this saved Python entry on a 1,510-file capture. It separates source orientation from 14 finite runtime observations, records an error shared by both readers and provides a recipe for reading large JSON evidence by field.
The HTTPX lazy-loading study uses saved Python questions on two fixed source captures, then separately checks six process import states. It shows why a lazy file-import fact and a local constructor bypass do not determine all transitive package loading.
| Captured source | Question and expected orientation | What requires source interpretation |
|---|---|---|
SymPy 16fa8553 |
Locate test_arch_init, lines 7–20 of sympy/physics/continuum_mechanics/tests/test_arch.py, and the separately fresh sympy/simplify/__init__.py dependency. |
Which object simplify denotes; a file dependency is not callable identity. |
SLF4J 9783320b |
Locate LoggerFactory.bind(), lines 181–215, and the separately fresh SLF4JServiceProvider.java target. |
Explicit provider selection, reflection, discovery and runtime classpath behavior. |
Both entries have matching captured/current text and no entry parse errors. Their normal question receipts now succeed as source orientation while calls.coverage stays unavailable, total and omitted stay null, and records stays empty. Success does not mean the question has been answered, the repository is parse-complete, or calls are known absent.
The test imports simplify from sympy and uses it in the final assertion at line 20. sympy/__init__.py:163 imports that name from the simplify package; sympy/simplify/__init__.py:7 imports it from the implementation module. The implementation is at simplify.py:435.
This finite source path supports the interpretation; it is not a call target emitted by the question CLI. The earlier SymPy study retains separate runtime object-identity evidence for its pinned environment. That runtime probe was not repeated or relabeled as this new feature's output.
Four overload stubs precede the implementation and share its captured qualname. Requesting --function simplify in that file still fails explicitly with task/function-unresolved; the tool does not silently select one. Omit the function selector and read the file when no captured qualname is unique.
At this historical revision, bind():181–215 reads the property and calls loadExplicitlySpecified. A non-null provider is initialized and returned before normal discovery. A null result proceeds to findServiceProviders(), choosing its first entry or using the no-operation fallback. loadExplicitlySpecified():217–236 reflects a class and constructor, with the listed instantiation/cast failures returning null. This does not promise fallback for every possible initialization error.
The property is slf4j.binding in this pinned source, not current-release configuration advice. Captured type/file references cannot determine which provider exists in a classpath, reflection outcome, or service descriptor. The earlier SLF4J study records separate bounded JVM/classpath observations; this change only improves the reading entry point.
- Require an exact entry in the saved file inventory, a matching captured language/producer, and the supported implementation extension. A suffix alone does not admit unknown or cross-language facts.
.pyiand JS/TS declaration files remain unsupported. - Reuse current-source equality, parse-error reporting, unique function selection, safe path reading and independent target freshness. Changed entries have no trusted location and retain exit 1; unreadable entries and ambiguous selections remain errors.
- Keep non-TS calls unavailable even if a capture carries a copied JS call model or reused adapter revision. No producer, schema, call-model or adapter-revision change is needed.
- Preserve JS/TS single-entry behavior and the separate fresh paired JS/TS workflow. No target application is executed by question orientation.
The two saved captures were recreated from public pins before publication: SymPy uses producer #1217 5eb24a20e2961faa559ba083ea223b6b172f95ed; SLF4J uses Labs bf0a29e7664f52973d06a8e6a608df2db1ecbd39. Both use default extraction settings. Recreated raw facts match the original captures byte for byte.
| Capture | Files | Import/type records | Function records | Parse errors |
|---|---|---|---|---|
| SymPy | 1,572 | 30,355 | 35,799 | 0 |
| SLF4J | 260 | 2,436 | 1,608 | 1 existing source-template error |
These are captured-record counts, not accuracy measures. The selected Java entry remains parse-clean despite the separate template error. The selected Python entry has three resolved file dependencies; the Java entry has 58 import/type records, 40 resolved and 18 unresolved. Repeated Java type references are not distinct calls.
The implementation's focused checks cover real adapter output, encoded Python freshness, normal CLI receipts, producer/inventory mismatch, parse errors, source drift, copied call-model metadata and ambiguous overloads. All 28 focused checks and all 284 Code Analysis module tests pass on official Node 22.23.2 and Python 3.13.16. The four newly selected tests on the exact parent yielded three failures and one passing rejection control. Independent scoped agent review found no actionable issue; it is not human acceptance.
Both source and unpacked-archive CLI results match after excluding only the installation-specific workflow path. The archive was built twice with identical SHA256 3f0a03a6d523fdf100779a5addc8d57c8e00dda36d854502e3e00d0915e4b22f. A fresh public fetch passed the complete reproduction below on its first run, including exact saved-fact hashes and the ambiguity control. Final-head CI completed with the sole README Classic motion-proof digest regression already reproduced on exact Labs (the same expected/actual hashes). The aggregate Node22 check consequently fails; all other executed jobs pass. CI is not green, and this remains an unmerged Draft without human review confirmation. No navigation-speed, reader-accuracy, whole-repository semantic coverage or runtime benefit is established by these two cases.
Run with official Node 22.23.2 on PATH and BAUIFY_PYTHON set to CPython 3.13.16. This is the self-contained script that passed the fresh public run. It installs analyzer dependencies in temporary checkouts; no live Archify installation is changed. It obtains exact public producer/consumer and target-source commits, recreates the saved captures, checks their hashes, then verifies source and unpacked-archive question outputs and the ambiguous-selection control. It does not execute SymPy or SLF4J applications.
Executed public reproduction
#!/usr/bin/env bash
set -euo pipefail
ARCHIFY_REF=${ARCHIFY_REF:-29f73e9c30ee72b3f085a2b13caedcaa50d1d4da}
ARCHIFY_ZIP_SHA256=${ARCHIFY_ZIP_SHA256:-3f0a03a6d523fdf100779a5addc8d57c8e00dda36d854502e3e00d0915e4b22f}
[[ "$ARCHIFY_REF" =~ ^[0-9a-f]{40}$ ]] && [[ "$ARCHIFY_ZIP_SHA256" =~ ^[0-9a-f]{64}$ ]] || { echo "Expected full lowercase commit SHA and archive SHA256" >&2; exit 1; }
node -e "if(process.version!=='v22.23.2') throw Error(process.version)"
: "${BAUIFY_PYTHON:?CPython 3.13.16 required}"
"$BAUIFY_PYTHON" -c 'import sys; assert sys.implementation.name == "cpython" and sys.version_info[:3] == (3,13,16),sys.version'
WORK=$(mktemp -d "${TMPDIR:-/tmp}/archify-lang-public.XXXXXXXX")
echo "Results and checkouts: $WORK"
cat > "$WORK/expected.json" <<'ARCHIFY_EXPECTED'
{
"frozenBeforeCandidateInspection": true,
"node": "v22.23.2",
"cases": [
{"id":"python","language":"py","revision":"16fa855354eb7bcabd3fe10993841e03b1382692","factsSha256":"dadc74bfe1a3a1d2f63b0e3b3308c7fc6a5485d00e2746ab35077de5891bf0c0","entry":"sympy/physics/continuum_mechanics/tests/test_arch.py","entrySha256":"b7f57e3edd1fc683ea603665e4b07a7a143884105596f79158bb045ddca8ff79","symbol":"test_arch_init","startLine":7,"endLine":20,"target":"sympy/simplify/__init__.py","targetSha256":"307d6f9301ead09e6d366eecb3c57abfe9a3ac31945f07ceb1aae22307e2dfc7","question":"Where does simplify used by test_arch_init come from, and why does a file dependency not prove object identity?"},
{"id":"java","language":"java","revision":"9783320b6c4411a0b120cad9e32cd9a981b1dac2","factsSha256":"b623d8fdacdf262cc28ec5fd0dbd83b5019af5821f5562569861a77702a7f50d","entry":"slf4j-api/src/main/java/org/slf4j/LoggerFactory.java","entrySha256":"472b6e31dd6d3010bc6aa61de2b84f78429bfd77514d696b4ac7d65bc41e2dcb","symbol":"LoggerFactory.bind()","startLine":181,"endLine":215,"target":"slf4j-api/src/main/java/org/slf4j/spi/SLF4JServiceProvider.java","targetSha256":"0a9694c77394e35a0fd40bd00e903f13bff834dcaabbbbc92aa272bc7bbc12d1","question":"What does LoggerFactory.bind do with an explicit provider before discovery, and what remains runtime dependent?"}
],
"calls":{"coverage":"unavailable","reason":"unsupported-or-unknown-call-model","total":null,"omitted":null,"records":[]},
"ambiguous":{"language":"py","entry":"sympy/simplify/simplify.py","symbol":"simplify","expected":"reject"}
}
ARCHIFY_EXPECTED
cat > "$WORK/validate-real.mjs" <<'ARCHIFY_VALIDATOR'
import fs from 'node:fs';
import path from 'node:path';
import assert from 'node:assert/strict';
import {spawnSync} from 'node:child_process';
import {createHash} from 'node:crypto';
const here=import.meta.dirname;
const [label,cli]=process.argv.slice(2);
assert.ok(['source','archive'].includes(label) && cli,'usage: node validate-real.mjs source|archive /absolute/path/to/archify.mjs');
assert.equal(process.version,'v22.23.2');
const hash=x=>createHash('sha256').update(x).digest('hex');
const expectedBytes=fs.readFileSync(path.join(here,'expected.json'));
assert.equal(hash(expectedBytes),'d34488379157cc7ffb2c2e5cbfc27427ca4a185c35a3dfda8e8019207d6e9dff');
const expected=JSON.parse(expectedBytes);
const moduleDir=path.resolve(path.dirname(cli),'../modules/code-analysis');
for(const pkg of ['typescript','ajv','java-parser'])assert.ok(fs.existsSync(path.join(moduleDir,'node_modules',pkg,'package.json')),pkg+' missing; do not enter installer');
assert.ok(!fs.existsSync(path.join(moduleDir,'.code-analysis-install.lock')),'dependency installer lock present');
const prior=path.resolve(here,'../..');
const inputs={
python:{analysis:process.env.PY_FACTS || path.join(prior,'python-package-exports/fixed-full'),receipt:path.join(prior,'python-package-exports/fixed-full-receipt.json'),root:process.env.PY_ROOT},
java:{analysis:process.env.JAVA_FACTS || path.join(prior,'java-provider/labs-head'),receipt:path.join(prior,'java-provider/labs-head-receipt.json'),root:process.env.JAVA_ROOT}
};
for(const [id,input] of Object.entries(inputs))if(!input.root)input.root=JSON.parse(fs.readFileSync(input.receipt)).root;
const run=(id,args)=>{
const r=spawnSync(process.execPath,[cli,'code-analysis','task',...args],{encoding:'utf8',timeout:120000,maxBuffer:8*1024*1024});
fs.writeFileSync(path.join(here,`${label}-${id}.stdout.json`),r.stdout||'');
fs.writeFileSync(path.join(here,`${label}-${id}.stderr.txt`),r.stderr||'');
fs.writeFileSync(path.join(here,`${label}-${id}.exit.json`),JSON.stringify({status:r.status,error:r.error?.message,signal:r.signal},null,2)+'\n');
return r;
};
const result=[];
for(const c of expected.cases){
const input=inputs[c.id];
const factsBytes=fs.readFileSync(path.join(input.analysis,'raw-facts.json'));
assert.equal(hash(factsBytes),c.factsSha256,c.id+' saved facts');
const facts=JSON.parse(factsBytes);
assert.equal(facts.repository.baseRevision,c.revision);assert.equal(facts.repository.language,c.language);
for(const [file,digest] of [[c.entry,c.entrySha256],[c.target,c.targetSha256]])assert.equal(hash(fs.readFileSync(path.join(input.root,file))),digest,file+' current source');
const head=spawnSync('git',['-C',input.root,'rev-parse','HEAD'],{encoding:'utf8'});assert.equal(head.status,0);assert.equal(head.stdout.trim(),c.revision);
const output=path.join(here,`${label}-${c.id}.brief.json`);
const r=run(c.id,[input.analysis,'--question',c.question,'--entry',c.entry,'--function',c.symbol,'--root',input.root,'--format','json','--out',output,'--json']);
assert.equal(r.status,0,r.stderr||r.stdout||String(r.error));
const receipt=JSON.parse(r.stdout),brief=JSON.parse(fs.readFileSync(output));
assert.equal(brief.kind,'archify-function-question');assert.equal(brief.stage,'orientation-only');
assert.equal(brief.entry.factsStatus,'valid');assert.equal(brief.entry.currentStatus,'ok');assert.deepEqual(brief.entry.parseErrors,[]);
assert.deepEqual(brief.entry.location,{file:c.entry,symbol:c.symbol,startLine:c.startLine,endLine:c.endLine});
const target=brief.imports.find(x=>x.to===c.target&&x.target?.factsStatus==='valid');
assert.ok(target,c.id+' independently fresh target');assert.equal(target.target.currentStatus,'ok');assert.equal(target.target.currentSha256,c.targetSha256);
for(const [key,value] of Object.entries(expected.calls))assert.deepEqual(brief.calls[key],value,`${c.id} calls.${key}`);
assert.equal(receipt.calls.coverage,'unavailable');assert.equal(receipt.calls.total,null);
if(label==='archive'){
const normalize=({workflow,...body})=>body;
assert.deepEqual(normalize(brief),normalize(JSON.parse(fs.readFileSync(path.join(here,`source-${c.id}.brief.json`)))),c.id+' source/archive');
}
result.push({id:c.id,revision:c.revision,location:brief.entry.location,target:c.target,targetStatus:target.target.factsStatus,coverage:brief.calls.coverage,total:brief.calls.total,exit:r.status,archiveParity:label==='archive'});
}
const a=expected.ambiguous,p=inputs.python;
const r=run('python-ambiguity',[p.analysis,'--question','Where is simplify defined?','--entry',a.entry,'--function',a.symbol,'--root',p.root,'--format','json','--json']);
assert.notEqual(r.status,0,'ambiguous selection must be rejected');
const reject=JSON.parse(r.stdout);assert.equal(reject.diagnostics?.[0]?.code,'task/function-unresolved');
const pythonFacts=JSON.parse(fs.readFileSync(path.join(p.analysis,'raw-facts.json')));
assert.ok(pythonFacts.functions.filter(f=>f.file===a.entry&&(f.name===a.symbol||f.qualname===a.symbol)).length>1,'expected multiple captured simplify definitions');
fs.writeFileSync(path.join(here,`${label}-results.json`),JSON.stringify({node:process.version,result,ambiguity:{exit:r.status,diagnostics:reject.diagnostics},meaning:'Saved source orientation only; imports do not establish runtime callable or provider identity.'},null,2)+'\n');
console.log(JSON.stringify({label,result,ambiguityExit:r.status}));
ARCHIFY_VALIDATOR
fetch() {
local url=$1 revision=$2 dest=$3 pattern=$4
git init -q "$dest"; git -C "$dest" remote add origin "$url"; git -C "$dest" config http.version HTTP/1.1
if [[ -n "$pattern" ]]; then git -C "$dest" config core.sparseCheckout true; printf '%s\n' "$pattern" > "$dest/.git/info/sparse-checkout"; fi
git -C "$dest" fetch -q --depth=1 --filter=blob:none origin "$revision"
git -C "$dest" checkout -q --detach FETCH_HEAD
test "$(git -C "$dest" rev-parse HEAD)" = "$revision"
}
fetch https://github.com/tt-a1i/archify.git "$ARCHIFY_REF" "$WORK/consumer" $'/archify/\n/archify.zip'
node - "$WORK/consumer/archify.zip" "$ARCHIFY_ZIP_SHA256" <<'JS'
const fs=require('node:fs'),c=require('node:crypto'),a=require('node:assert/strict');const sha=c.createHash('sha256').update(fs.readFileSync(process.argv[2])).digest('hex');a.equal(sha,process.argv[3]);console.log('Archive SHA256:',sha);
JS
mkdir "$WORK/archive"
unzip -q "$WORK/consumer/archify.zip" -d "$WORK/archive"
fetch https://github.com/tt-a1i/archify.git 5eb24a20e2961faa559ba083ea223b6b172f95ed "$WORK/py-producer" '/archify/'
fetch https://github.com/tt-a1i/archify.git bf0a29e7664f52973d06a8e6a608df2db1ecbd39 "$WORK/java-producer" '/archify/'
for dir in "$WORK/py-producer/archify/modules/code-analysis" "$WORK/java-producer/archify/modules/code-analysis" "$WORK/consumer/archify/modules/code-analysis" "$WORK/archive/archify/modules/code-analysis"; do (cd "$dir" && npm ci --ignore-scripts --no-audit --no-fund); done
fetch https://github.com/sympy/sympy.git 16fa855354eb7bcabd3fe10993841e03b1382692 "$WORK/sympy" ''
fetch https://github.com/qos-ch/slf4j.git 9783320b6c4411a0b120cad9e32cd9a981b1dac2 "$WORK/slf4j" ''
node "$WORK/py-producer/archify/bin/archify.mjs" code-analysis check "$WORK/sympy" --language py --fail-on never --json --out "$WORK/py-facts" > "$WORK/py-receipt.json"
node "$WORK/java-producer/archify/bin/archify.mjs" code-analysis check "$WORK/slf4j" --language java --fail-on never --json --out "$WORK/java-facts" > "$WORK/java-receipt.json"
export PY_ROOT="$WORK/sympy" JAVA_ROOT="$WORK/slf4j" PY_FACTS="$WORK/py-facts" JAVA_FACTS="$WORK/java-facts"
node "$WORK/validate-real.mjs" source "$WORK/consumer/archify/bin/archify.mjs"
node "$WORK/validate-real.mjs" archive "$WORK/archive/archify/bin/archify.mjs"
echo "Verified; results retained at $WORK"