6 Commits

Author SHA1 Message Date
Vijay Janapa Reddi
a74c98576e Merge origin/dev into yaml-audit
Sync the yaml-audit branch with the latest dev work since the previous
sync (5c5af75ed). Brings in 73 commits including:

  - CI security fixes: postcss XSS bump, uuid bounds bump, codeql
    paths-ignore for vendored bundles, read-only token on
    staffml-validate-vault workflow
  - kits/ dark mode polish: code-block readability, dropdown contrast
  - vault-cli/: pre-commit ruff hook + 20 ruff fixes, all-contributors
    auto-credit workflow change to pull_request_target
  - dev's earlier merge of yaml-audit (836d481b5) carrying the
    pre-trailer-strip Phase 1/2/3 history; this merge harmonises that
    with the current trailer-clean yaml-audit tip
  - misc bug fixes (tinytorch perceptron seed, infra workflows,
    socratiq vite dev injector)

Conflicts resolved (if any) preserve the yaml-audit-side authoritative
state for vault/* files (we own those) and the dev-side authoritative
state for .github/workflows/* and other shared infrastructure.

# Conflicts:
#	.github/workflows/all-contributors-auto-credit.yml
#	.github/workflows/staffml-preview-dev.yml
#	interviews/staffml/src/data/corpus-summary.json
#	interviews/staffml/src/data/vault-manifest.json
#	interviews/staffml/tests/chain-and-vault-smoke.mjs
#	interviews/vault-cli/README.md
#	interviews/vault-cli/docs/CHAIN_ROADMAP.md
#	interviews/vault-cli/scripts/build_chains_with_gemini.py
#	interviews/vault-cli/scripts/generate_question_for_gap.py
#	interviews/vault-cli/scripts/merge_chain_passes.py
#	interviews/vault-cli/scripts/validate_drafts.py
#	interviews/vault-cli/src/vault_cli/legacy_export.py
#	interviews/vault-cli/tests/test_chain_validation.py
#	interviews/vault/.gitignore
#	interviews/vault/ARCHITECTURE.md
#	interviews/vault/chains.json
#	interviews/vault/id-registry.yaml
#	interviews/vault/questions/edge/optimization/edge-2536.yaml
#	interviews/vault/questions/mobile/deployment/mobile-2147.yaml
#	tinytorch/src/03_layers/03_layers.py
2026-05-02 11:06:43 -04:00
Vijay Janapa Reddi
2b3cf5e1da chore(vault): consolidate AI pipeline artifacts under _pipeline/
Establishes one ignored subdirectory for ALL intermediate outputs of
LLM-driven tooling (chain proposals, gap detection, draft scorecards,
audit traces). Single gitignore rule: /_pipeline/.

Convention is documented in interviews/vault/README.md under "Pipeline
artifacts" — it's a real project layout convention, not AI-specific
config.

Path migration:
  interviews/vault/chains.proposed*.json
                  → _pipeline/chains.proposed*.json
  interviews/vault/gaps.proposed*.json
                  → _pipeline/gaps.proposed*.json
  interviews/vault/draft-validation-scorecard.json
                  → _pipeline/draft-validation-scorecard.json
  interviews/vault/audit-runs/
                  → _pipeline/runs/

8 scripts updated to define a PIPELINE_DIR constant and route default
outputs through it: build_chains_with_gemini.py,
apply_proposed_chains.py, merge_chain_passes.py, validate_drafts.py,
audit_chains_with_gemini.py, generate_question_for_gap.py,
summarize_proposed_chains.py, promote_drafts.py.

Forward-looking docs (README.md chain-pipeline section + CHAIN_ROADMAP.md
resume instructions + state snapshot) updated to reference the new
paths. Historical Progress Log entries left as-is — they accurately
describe what was committed at the time.

Drive-by .gitignore fixes (both used full repo-relative paths under
package-local .gitignore files, which never matched):
  interviews/vault-cli/.gitignore: scripts/.calibration_cache/
  interviews/vault/.gitignore:     /embeddings.npz

Validation:
  - vault check --strict: 10,705 loaded, 0 invariant failures
  - pytest interviews/vault-cli/tests/: 74/74
  - audit --dry-run: paths resolve correctly to _pipeline/runs/<ts>/

No durable corpus content moves. chains.json (live registry),
id-registry.yaml, questions/, etc. all stay where they were.
2026-05-02 09:04:55 -04:00
Vijay Janapa Reddi
d272d374aa feat(chains): --mode lenient + tier field for second-pass coverage
Phase 1.2 + 1.3 of CHAIN_ROADMAP.md. The two land together because the
prompt template, validator Δ-rule, and tier-tagging must stay in lockstep
or chains.proposed.lenient.json would mis-validate.

build_chains_with_gemini.py:
  - new LENIENT_PROMPT_TEMPLATE alongside renamed STRICT_PROMPT_TEMPLATE;
    lenient template tells Gemini to accept Δ ∈ {0,1,2,3}, with Δ=0 only
    for shared-scenario same-level pairs and Δ=3 last-resort
  - MODE_CONFIG single-source-of-truth maps mode → (template, allowed Δ set)
  - validate_chain now takes mode= and gates on the per-mode Δ set
  - process_batch tags lenient-mode chains with tier="secondary" and
    a chain_id suffix (-secondary) so primary/secondary IDs never collide
  - new --mode {strict,lenient} flag (default strict — primary chains
    keep producing under the same rules as before)
  - new --buckets-from <chain-coverage.json> flag that restricts the run
    to the uncovered_buckets list from diagnose_chain_coverage.py
    (the Phase 1.4 second-pass entry point)

apply_proposed_chains.py:
  - docstring note: tier field is intentionally not validated here
    (it's a UI hint, not a structural invariant)
  - already accepts Δ=0 chains via its non-strict monotonicity check, so
    no logic change needed

tests/test_chain_validation.py:
  - 19 cases covering both modes: strict accepts +1/+2 and rejects Δ=0,
    Δ≥3, and backward; lenient accepts Δ=0/Δ=3 but still rejects Δ≥4 and
    backward; both modes reject size-out-of-range, multi-topic, and
    unknown qids. Loads the script via importlib (it's not part of the
    importable vault_cli package).

Smoke check (--dry-run --buckets-from chain-coverage.json --mode lenient):
17 calls planned for the 211 uncovered buckets, well under the 200 cap.
2026-04-30 19:29:12 -04:00
Vijay Janapa Reddi
4b785ce26d feat(chains): --mode lenient + tier field for second-pass coverage
Phase 1.2 + 1.3 of CHAIN_ROADMAP.md. The two land together because the
prompt template, validator Δ-rule, and tier-tagging must stay in lockstep
or chains.proposed.lenient.json would mis-validate.

build_chains_with_gemini.py:
  - new LENIENT_PROMPT_TEMPLATE alongside renamed STRICT_PROMPT_TEMPLATE;
    lenient template tells Gemini to accept Δ ∈ {0,1,2,3}, with Δ=0 only
    for shared-scenario same-level pairs and Δ=3 last-resort
  - MODE_CONFIG single-source-of-truth maps mode → (template, allowed Δ set)
  - validate_chain now takes mode= and gates on the per-mode Δ set
  - process_batch tags lenient-mode chains with tier="secondary" and
    a chain_id suffix (-secondary) so primary/secondary IDs never collide
  - new --mode {strict,lenient} flag (default strict — primary chains
    keep producing under the same rules as before)
  - new --buckets-from <chain-coverage.json> flag that restricts the run
    to the uncovered_buckets list from diagnose_chain_coverage.py
    (the Phase 1.4 second-pass entry point)

apply_proposed_chains.py:
  - docstring note: tier field is intentionally not validated here
    (it's a UI hint, not a structural invariant)
  - already accepts Δ=0 chains via its non-strict monotonicity check, so
    no logic change needed

tests/test_chain_validation.py:
  - 19 cases covering both modes: strict accepts +1/+2 and rejects Δ=0,
    Δ≥3, and backward; lenient accepts Δ=0/Δ=3 but still rejects Δ≥4 and
    backward; both modes reject size-out-of-range, multi-topic, and
    unknown qids. Loads the script via importlib (it's not part of the
    importable vault_cli package).

Smoke check (--dry-run --buckets-from chain-coverage.json --mode lenient):
17 calls planned for the 211 uncovered buckets, well under the 200 cap.
2026-04-30 19:29:12 -04:00
Vijay Janapa Reddi
d8a55f3334 feat(chains): tighten progression rules + allow up to 2-chain membership
Gemini prompt + structural validator now enforce:
  - Consecutive Bloom delta MUST be 1 or 2 (rejects Δ=0 same-level pairs
    and Δ≥3 huge jumps; backward steps already impossible)
  - Strict +1 preferred; +2 accepted only when no +1 candidate exists
  - A question can appear in up to 2 chains, but only if it's L1 or L2
    (foundational anchor pattern); 3+ chain memberships are rejected as
    over-stuffing

Empirical alignment: 70% of legacy chains were strict +1, 19% had +2
jumps, 8% had +3 jumps that we now reject as too-large pedagogical
moves. The new rules tighten quality while keeping the bulk of
defensible existing structure expressible.
2026-04-30 08:58:38 -04:00
Vijay Janapa Reddi
8423dcb08f feat(vault-cli): Gemini-powered chain builder + apply script
build_chains_with_gemini.py — adaptive batched chain proposal:
  - Buckets corpus by (track, topic), packs into ~80K-token batches
  - Calls gemini-3.1-pro-preview with structured-output prompt
  - Validates each proposed chain (size 2-6, monotonic, single-topic,
    members exist, no cross-chain duplicates)
  - Writes staging chains.proposed.json (never touches live registry)

Full-corpus plan: 313 buckets pack into 44 calls (well under 250/day Pro
cap, uses ~70K input tokens per call out of 1M context).

Test on tinyml:network-bandwidth-bottlenecks (6 questions) -> 2 well-formed
chains, Bloom-monotonic with coherent rationale (Hailo-8 PCIe arc + BLE
network arc).

apply_proposed_chains.py — gated migration:
  - Re-validates staging file against live YAML corpus
  - Backs up chains.json -> chains.json.bak
  - Refuses to apply if any structural invariant fails
2026-04-30 08:53:06 -04:00