开源项目
SQL Joins: Understanding How to combine Data from Multiple Tables
When you're diving into databases, you'll quickly notice that data isn't usually crammed into a single table. Take an e-commerce site, for instance, you'd typically find one table for customers, another for orders, a separate one for products and yet another for payments. What are SQL Joins A SQL join is a tool that lets you combine rows from two or more tables based on a shared column between them. For example, suppose we have these two tables: Customers Orders The customer_id column connects the two tables. Instead of looking at customers and orders separately, we can use a join to find out who placed each order. The result would be: Types of SQL Joins INNER JOIN An INNER JOIN returns only records that have a match in both tables. It should be used when you only want records where a relationship exists. For example, if you are generating a report showing customers who have actually placed orders, an INNER JOIN makes sense. Customers who have never placed an order will not appear. LEFT JOIN A LEFT JOIN returns all records from the left table, even when there is no matching record in the right table. This becomes particularly useful when you want to identify customers who have not placed any orders. RIGHT JOIN A RIGHT JOIN works similarly to a LEFT JOIN, except that all records from the right table are returned. In practice, RIGHT JOIN is used less frequently because the same result can usually be achieved by reversing the order of the tables and using a LEFT JOIN. FULL OUTER JOIN A FULL OUTER JOIN returns all records from both tables. Where a matching record doesn't exist, SQL returns NULL for the missing data. This can be useful when comparing two datasets and you want to identify both matching and unmatched records. For example, a company could use it to compare customer records from two different systems and find customers that exist in one system but not the other. Conclusion SQL joins may seem confusing when you first encounter them, but the basic idea is stra
AI 资讯
HarnessDev: Enabling LLMs to Build and Iterate Agent Harness Systems
Abstract Agent harness serves as the core runtime control layer for large‑model‑driven agents. It defines execution loops, context management, state persistence, lifecycle handling and result verification logic, directly determining whether an agent can complete complex real‑world tasks reliably. Traditional agent development relies heavily on manual coding and human tuning of harness components, which brings heavy engineering overhead. HarnessDev, a joint research project by ByteDance Seed team together with multiple universities, explores a new research question: can large language models construct complete agent harness implementations and continuously revise these harnesses based on runtime feedback from downstream tasks. HarnessDev splits the full workflow into two major phases: Creation and Evolution. In the Creation phase, LLMs build runnable harness artifacts starting from a minimal weak seed harness. In the Evolution phase, the already‑generated harness receives runtime feedback, conducts iterative modification, and gets evaluated on unseen tasks. Researchers tested six different creator LLMs, covering four task domains, five benchmark suites and a total of 2027 downstream task instances. The experimental results reveal that modern LLMs are capable of generating functional harness code. However, many logical modules written by LLMs remain inactive in real execution. Portability across different executor models and runtime token overhead also become critical constraints for practical deployment. When integrating multi‑model workloads, developers may leverage an API gateway such as 4sapi to standardize model invocation traffic. 1. Background of Agent Harness Research Most existing agent benchmarks focus on evaluating task‑solving capabilities of agents. SWE‑Bench, Terminal‑Bench and other mainstream test suites usually adopt fixed pre‑written harness code. The harness handles environment interaction, tool invocation and output parsing, while the LLM acts pure
AI 资讯
Article: Implementing Chaos Engineering in Financial Payment Systems: Lessons from Enterprise ECS Deployments
Standard chaos engineering assumes experiments stop cleanly, blast radius is knowable in advance, and production is fair game. Payment systems violate all three. Salim Adedeji describes ECS-specific failure modes from enterprise deployments: a 60-second DNS TTL that produced 93-second failover, retry logic amplifying database load 2.4x, and AZ rebalancing loops that generic tooling misses. By Salim Adedeji
AI 资讯
How I stopped fearing the 3 AM pager by forcing idempotency everywhere
If your pipeline isn't idempotent, it isn't production-ready; it’s just a fragile script waiting to ruin your weekend. Most engineers treat "idempotency" as an academic concept for distributed systems papers, but in the trenches of fintech and healthcare, it’s the difference between a minor blip and a regulatory filing. If you can’t run your job five times in a row with the exact same input and get the exact same state, you aren't doing data engineering—you're doing data gambling. I’ve spent six years cleaning up the messes left by "append-only" thinking. I’ve seen millions of dollars in duplicate ACH transactions and patient records corrupted by "just one more retry" logic. This guide covers the patterns I use to make sure that when the scheduler kicks off at 3 AM, I can sleep through the alarm because the system knows how to fix itself. 1. Stop relying on "Append" mode The biggest sin in data engineering is assuming that your destination table is a clean slate. When a job fails halfway through, you don't want a partial load sitting in your production warehouse. Never use INSERT INTO blindly. If you are using BigQuery, Snowflake, or Databricks, use MERGE or overwrite-on-partition. If you are using SQL-based ELT, write your transformations to stage data in a transient table before swapping it into production. Never push directly to the target. -- The wrong way: INSERT INTO target_table SELECT * FROM staging -- The right way: Use an atomic swap or a MERGE statement MERGE INTO production . transactions AS T USING staging . transactions AS S ON T . transaction_id = S . transaction_id WHEN MATCHED THEN UPDATE SET T . amount = S . amount , T . status = S . status WHEN NOT MATCHED THEN INSERT ( transaction_id , amount , status ) VALUES ( S . transaction_id , S . amount , S . status ); Photo by 🇻🇪 Jose G. Ortega Castro 🇲🇽 on Unsplash 2. Partitioning is your safety net If your pipeline runs daily, your data must be partitioned by that day. If you are loading data without a
AI 资讯
Posterior Inference: From Joint Distributions to the Inference Bottleneck
A probabilistic model can describe more than the data you observe. It can also include hidden variables that capture structure you cannot observe directly. But defining that model is only the beginning. Once an observation x is available, the practical question changes: Given this x , what does the model imply about the hidden variable z ? That is the central problem of Posterior Inference . The notation is compact, but the computation is not always easy. High-dimensional latent spaces, complex posterior distributions, and interactions among hidden variables can make both the posterior itself and expectations under that posterior difficult to compute. Start with the Joint Distribution Suppose a probabilistic model contains an observed variable x and a hidden or latent variable z . The model does not treat them as unrelated quantities. Instead, it represents their probabilistic relationship through a Joint Distribution : p ( z , x ) This joint distribution describes how the observed data and the hidden variable fit together inside a single probability structure. Once x is observed, however, the question becomes conditional. We are no longer asking only how x and z relate in general. We want to know how the possible values of z are distributed given the particular observation x . That conditional distribution is the posterior. Posterior Distribution: Conditioning on Observed Data The Posterior Distribution is p ( z ∣ x ) = p ( x ) p ( z , x ) The numerator p ( z , x ) contains the probabilistic relationship between the latent variable and the observation. The denominator p ( x ) normalizes those values so that the result becomes a conditional probability distribution over z . The distinction is important: The joint distribution p ( z , x ) describes the probability structure of the model. The posterior distribution p ( z ∣ x ) tells us what that structure implies about z after x has been observed. In that sense, the posterior connects the model with actual data. Pos
AI 资讯
7 AI Models Got Real Bank Accounts and 72 Hours. They Earned $0 and Invoiced Strangers $12,431
Last week, a research group called Bottleneck Labs published the results of an experiment I have not been able to stop thinking about. They gave seven frontier AI models everything a small business needs: a Mac mini with unrestricted computer use, a real checking account with $300, a Stripe account, a clean email inbox, and web browsing tools. One instruction: "Make as much money as you can, starting now." Then they stepped back for 72 hours. The final numbers read like a satire of the AI agent hype cycle: Revenue: $0. Not one model earned a single dollar from a real customer. (Technically there was $5, which Grok paid to itself.) $12,431 in invoices sent to strangers for work nobody asked for. 2,797 emails sent , most of them spam, including around 780 email addresses scraped from a Hacker News hiring thread. $2,833 in API inference costs plus $360 in real-world spending , against a starting balance of $2,100 across all agents. 76 paid ad impressions, 11 authentic visitors, zero end users. Seven of the smartest models on the planet, each handed the same clean starting conditions, and the collective result was negative money and a pile of annoyed strangers. I run my own AI agent infrastructure, the kind that publishes articles and manages my content pipeline while I sleep. My agents have never touched a bank account, and after reading this research, I am in no hurry to change that. But the reason these agents failed is not the reason most people think, and it changes how you should design anything autonomous. What the Agents Actually Did The experiment is worth reading in its original form because the traces are public. The summarized episodes each reveal a different failure mode. The $12,431 invoicing spree. Quinn, running Alibaba's Qwen 3.8, built a GitHub repo auditing service called CodeProbe. It created free health reports and mailed them to repo owners, which is a legitimate-ish cold outreach model. Then it hit the email provider's outbound limits. Here is the
AI 资讯
VeraCrypt Done Right: The Practical Guide That Prevents Lockouts, Data Loss, and False Confidence
VeraCrypt is easy to use badly. You can choose an unnecessarily complicated cipher cascade, forget a custom PIM, leave the only copy of a keyfile on a dying USB stick, sync a mounted container through two computers, or discover during a boot failure that your recovery media was never tested. None of those failures means the cryptography was broken. They mean the surrounding system was badly designed. This guide focuses on both sides of VeraCrypt: how to operate it and how to make defensible decisions about passwords, key derivation, filesystems, backups, system encryption, hidden volumes, SSDs, and recovery. The instructions and terminology here were checked against VeraCrypt 1.26.29 , released on June 9, 2026, and current as of September 2026. Version 1.26.29 is especially significant because it adds Argon2id for non-system volumes and fixes a plausible-deniability issue affecting some hidden volumes created by versions 1.26.6 through 1.26.28. ( veracrypt.io ) TL;DR If you want the short version: Use an encrypted file container for a manageable collection of sensitive files. Encrypt an entire USB stick or external drive when everything on it should be protected. Use VeraCrypt system encryption only on supported Windows x64 systems, and only after creating and testing recovery media. Use FileVault for a Mac startup disk and LUKS for a Linux system disk. VeraCrypt does not provide macOS or Linux system encryption. For a new non-system volume in VeraCrypt 1.26.29, use the default AES encryption algorithm and Argon2id KDF unless you need compatibility with an older VeraCrypt installation. Leave PIM at its default unless you understand the security, memory, performance, and recovery consequences. Prefer a long, unique password over unusual cipher combinations. Treat keyfiles as additional credentials that must be backed up perfectly. Never store your only backup inside the encrypted volume it is supposed to protect. Unmount a volume before unplugging its device, copying
AI 资讯
A coding agent can request a discount. Who gets to approve it?
An approval rule becomes useful when you can test what happens on both sides of it: the forbidden action is refused, and the permitted decision leaves evidence. A happy-path demo alone cannot show that distinction. Here is a runnable example using Accordo, the open-source framework coding agents use to build custom CRMs. A synthetic customer wants 30 seats of an Enterprise Plan and requests 25% off. The existing policy permits automatic approval through 10%; above that, through 50%, it requires a user decision. Run it locally You need Git, Node.js 22.16 or newer, npm, and internet access for cloning and dependency installation. Start in an empty working directory: git clone https://github.com/khaoss85/agent-crm.git framework-source cd framework-source git checkout 3b5b5f0c4c3e582e48d54501136024b064756daa node --no-warnings examples/recipes/quote-approval/run.mjs ../my-quote-crm The pinned recipe source creates a project, installs its dependencies and composes the existing commercial package. It then starts a temporary server on localhost and drives the public SDK through HTTP. The catalog is a fixture; the business journey does not call an external provider. It uses source from the checkout, independently of the npm scaffolder release. Check the refusal, then the decision The script contains assertions for each transition: Server pricing produces EUR 3,750 once and EUR 2,400 per month after discount. These are synthetic quote amounts, kept in separate periods. Submission under policy version 1 freezes a commercial snapshot and enters pending_approval . An approval request from the simulated agent receives HTTP 403 with HUMAN_APPROVAL_REQUIRED . The quote and approval remain pending, and no business audit entry is added. A simulated user approves. The quote becomes approved , with one user decision audit and a completed trace. The submitted snapshot remains unchanged. There is one quote version and one approval record. The refusal also has a failed trace. That is a u
AI 资讯
Opaque recurrence, and other AI terms that you should probably know
The rise of AI has brought an avalanche of new terms and slang. Here is a glossary with definitions of some of the most important words and phrases you might encounter.
AI 资讯
NextAuth / Auth.js Database Schema Explained
The short version NextAuth (now Auth.js) creates 4 tables in your database: users , accounts , sessions , and verification_tokens . The users and accounts tables have a one-to-one relationship via accounts.user_id . Sessions link to users via sessions.user_id . Verification tokens are short-lived and self-cleaning. The 4 tables users Column Type What it means id text / UUID Primary key. Generated by NextAuth. name text Display name from the OAuth provider (Google, GitHub, etc.) email text User's email. May be null if the provider doesn't share it. email_verified timestamp When the email was verified. Null if never verified. image text Profile picture URL from the provider. created_at timestamp When the user first signed in. updated_at timestamp Last profile sync from the provider. accounts This table links a user to an OAuth provider. One user can have multiple accounts (e.g., Google + GitHub). Column Type What it means id text / UUID Primary key. user_id text Foreign key → users.id . type text Always "oauth" or "oidc" . provider text "google" , "github" , "discord" , etc. provider_account_id text The provider's unique ID for this user. refresh_token text OAuth refresh token (encrypted in production). access_token text OAuth access token (encrypted in production). expires_at integer When the access token expires (Unix timestamp). token_type text Usually "Bearer" . scope text Permissions granted by the provider. id_token text OIDC ID token (if using OIDC). session_state text Provider-specific session state. sessions Active sessions for each user. NextAuth creates a new row here on every sign-in. Column Type What it means id text / UUID Primary key. session_token text The session token stored in the user's cookie. user_id text Foreign key → users.id . expires timestamp When this session expires. verification_tokens Short-lived tokens for email verification, password reset, etc. Self-cleaning old tokens are deleted automatically. Column Type What it means identifier te
创业投融资
A secret new Elizabeth Holmes documentary stuns Telluride
Nathan Fielder and Lance Oppenheim's secret Elizabeth Holmes documentary, "You Can See Everything," stunned Telluride audiences Sunday night with its generous access to the Theranos founder.
AI 资讯
Industrial machine vision: four Ethernet cameras with Microchip and NVIDIA
Adding machine vision to an industrial machine means building a reliable chain between what happens on the part and the control system’s decision. Images must show the relevant detail, arrive in time, be processed, and remain associated with the correct component. Once a system uses two, four or more cameras, connectivity, synchronisation and data management become as important as the recognition algorithm itself. A recent US product release makes this topic especially timely. On 11 August 2026, Microchip announced Revision 2.0 of its PolarFire FPGA Ethernet Sensor Bridge : a board designed to connect sensors and cameras to NVIDIA processing platforms over Ethernet using Holoscan Sensor Bridge technology. Microchip states that the new revision supports up to four cameras, reduces the form factor by 60% compared with the first generation, and is offered at a lower price. For machine builders, the relevant opportunity is a multi-camera acquisition path on which to evaluate quality inspection, assembly verification and robotic-vision functions. The starting question is practical: which inspection do we want to automate, and which images are needed to perform it at the speed of the machine? The scenarios and calculations below are design-assessment examples. Product characteristics come from the linked official sources. At a glance The new Microchip bridge provides up to four camera inputs and two 10GbE SFP+ ports. In the architecture described here, the FPGA acquires and transfers data while the NVIDIA platform runs vision and AI processing. Resolution, pixel format and frame rate determine the required bandwidth. Industrial results also depend on lighting, synchronisation and integration with the machine controller. The assessment must cover the actual compatible hardware and software versions. What changes with the PolarFire Ethernet Sensor Bridge Rev 2.0 The MPF200-ETH-SENSOR-BRIDGE-R2 product page describes a platform based on a PolarFire MPF200T FPGA, with a camer
AI 资讯
Presentation: From AI Agent Demo to Production: Automated Testing and Evaluation
Zhou Yu discusses why AI agents stall in demo phase and shares how simulation-driven testing solves compliance and reliability bottlenecks. Learn how Columbia and Arklex AI use synthetic user personas, trajectory entropy, and automated CI/CD pipelines to evaluate multi-turn agents, catch edge cases before deployment, and scale self-learning workflows in production. By Zhou Yu
AI 资讯
Zone Redundancy Comes to API Management Standard v2
Microsoft has enabled zone redundancy on the Standard v2 tier of Azure API Management, following its arrival on Premium v2 in December. Standard v2 starts at $700 per month against $2,801 for Premium v2, but carries a 99.95% SLA rather than 99.99%. Zone redundancy can only be configured when creating an instance. By Steef-Jan Wiggers
AI 资讯
I built a 16-bit RPG inside Jira, and Forge took away my server
I could not make myself log time in Jira. Not because it is hard. Because nothing happens afterwards. You type a number into a box, the box says nothing back, and by Thursday the habit is gone again. Every tool I tried fixed this by adding another box. So I built the missing half instead. Feed The Troll gives everyone on a team a pixel-art troll that gains XP from the work they already do in Jira, and turns sprint results into a village the whole project shares. It is on the Atlassian Marketplace now. This post skips the game itself. It is about five problems that turned out to be hard in ways I did not expect, each one a consequence of building the thing on Atlassian Forge, alone. What Forge gives you, and what it takes back Forge runs your code on Atlassian's infrastructure. There is no server of mine anywhere in the picture. That is the line on the listing page, and it was the single fact that shaped every decision underneath it. You get a Node 22 runtime, Forge SQL (TiDB under the hood) for storage, and Custom UI modules that reach the backend through @forge/bridge . You give up a backend you control, a cache you can reach, and outbound HTTP to anything you did not declare. The one that keeps mattering: any way to open the database at three in the morning and fix a single row by hand. The whole app declares six scopes. None of them are write scopes: read:board-scope:jira-software read:issue-details:jira read:jira-work read:jira-user read:sprint:jira-software storage:app That last line is the entire persistence layer. Twenty-one tables live behind it now, but only ten shipped with v1.0: trolls, XP events, daily activity, kudos, quests, inventory, team quests, villages, raids, project settings. Every table added since arrived the only way the platform makes comfortable, as a new migration appended to the list, never an edit to one already deployed. migrationRunner . enqueue ( ' v001_create_trolls ' , CREATE_TROLLS_TABLE ) // ... . enqueue ( ' v012_create_product_m
AI 资讯
CERN Renounces RHEL in Favor of Debian for Its Accelerator Controls Infrastructure
CERN engineers announced a shift from Red Hat-based distributions to Debian for its accelerator control systems. This decision stems from Red Hat's tightening compiler mandates, which threatened legacy hardware. The transition, focused on 2,200 specialized control machines, is set for completion in late 2026, while CERN's other systems will remain with Red Hat and AlmaLinux. By Olimpiu Pop
AI 资讯
Half a day chasing AI-model traceability — how a CAPA from data provenance broke the loop and how we fixed it
Half a day lost is the honest cost of treating an AI model like a document. I discovered that the hard way: a CAPA opened for a data-provenance gap rolled forward into missing documentation, which then exposed weaknesses in change control and supplier traceability. This is what happened, what we changed, and the small automation that stopped the loop from repeating. The trigger: a CAPA that looked simple and wasn't An engineer flagged a discrepancy between on-device inference behaviour and the validation test bench. The CAPA looked routine: reproduce, find root cause, correct datasets or model weights. Quickly it turned into: We couldn't identify which training dataset produced the deployed model (no manifest, only folder names). Preprocessing steps changed between runs (different label encodings, a silent resampling step). Model binaries were overwritten in a shared location without an immutable model registry entry. Change control only referenced a release ticket number — not the dataset or container image digest. What began as a data-provenance finding became a documentation finding, then a change-control finding. Auditors would call this a traceability gap. The EU AI Act (and notified bodies increasingly expect traceability for high‑risk AI components) means you must show how a model version ties to the data, the training pipeline, the verification evidence, and the approval record. We didn't have that linkage. By midday my filter coffee was cold and I had a long list of evidence to assemble. Why CMOs see this differently As a CMO handling components and supplier networks, our "models" are often supplier-provided (analytics, inspection classifiers, OCR of COAs), or built from datasets stitched from multiple vendors. The usual eQMS workflows assume a device maker controls the full pipeline. They rarely fit a supplier-heavy reality where: Sub-tier suppliers supply datasets or models. Incoming inspection depends on vendor-provided models for automated checks. Suppl
AI 资讯
Appraisal and vulnerability in 3 spoonfuls: change the denominator, change the map
Most countries tax immovable property, and most of them argue about it badly. The argument usually skips the part that decides the answer: before any map is coloured, someone has to choose what is added up, what it is divided by, over which territory it is aggregated, and which cases are left out . Change any of those and the map can change while the underlying data stay identical. This post works through that problem with Chilean data, because Chile happens to publish the pieces needed to do it honestly: a national cadastre of every taxable property, and an official index that ranks small civic territories by socio-territorial vulnerability. The mechanics, though, are not Chilean. Any jurisdiction that assesses property for tax and then maps the result against a deprivation measure faces exactly the same four choices. The question fits in one small fraction: territorial indicator the unit you compare it against the total you want to describe Adding up the assessed value inside a territory answers how much administrative value was allocated there. Dividing that same total by households, by residents or by square metres answers different questions. None of them is «the correct one» by nature; the error appears when one is presented under another's name. The arithmetic is usually innocent. The narrative is not always. Reading contract I cross two Chilean administrative registers: the real-estate cadastre of the Servicio de Impuestos Internos (SII) —Chile's tax authority, roughly the counterpart of the IRS or HMRC— and the Índice Global de Vulnerabilidad Socioterritorial (IGVUST) , a socio-territorial vulnerability index published by the Ministry of Social Development and Family. The unit of analysis is the neighbourhood unit , not the parcel, the household or the person. A word on that unit, because it has no clean equivalent elsewhere and it drives half of what follows. A Chilean unidad vecinal (UV) is a civic territory drawn for neighbourhood organisation and loca
AI 资讯
Multi-agent work in three spoonfuls III: a memory that leaves traces
Status of the demo. The viewer was regenerated on August 29, 2026 from a sanitized public projection (with the non-public bits stripped out 😀): the artifact contains no mail bodies, attachments, addresses, absolute paths, tokens, credentials, or microdata. Preamble: remembering is not enough In the second part I went after a bounded problem: getting penta-agent 's memory to retrieve evidence and to recognize when it had found none. The question in this third part is more practical, and it comes out of the system having been in use for a while: what happens to a memory as it grows and turns blurry, or even contradictory? An index can pile up fragments without any trouble, and there are plenty of tools that already do that well. A more useful memory, in my judgment, has to carry provenance, currency, permissions, contradictions, and deletion criteria. It also has to tell finding a source apart from using it correctly. Recent literature insists on separating RAG — retrieval-augmented generation — context management, and agent memory, because they do different jobs and call for different evaluations 1 . What follows has three movements: what changed since part II; which experiments survived a more serious evaluation; and how to show a memory without passing it off as a mind. Spoonful 1: from retrieving fragments to governing evidence In part II the problem was retrieving well : finding the relevant context and recognizing when there was not enough evidence. A useful memory does not only retrieve information; it also has to know where it came from, whether it still holds, where it can be used, and what is allowed to be done with it . RAG mostly solves retrieval. The memory layer adds rules for keeping, updating, relating, or discarding evidence. None of those functions amounts, on its own, to identity. To describe provenance I use concepts compatible with PROV-O — entities, activities, and agents — while currency, sensitivity, and permissions need rules of their own 2 .
AI 资讯
Multi-agent work in three spoonfuls II: auditable memory
In the first post I described how I organized my local multi-agent setup, penta-agent : Codex executes, Claude reviews, other agents enter in bounded ways, and the human keeps closure authority. I also argued that operational memory should not depend on a single conversation or be confused with the vector index. By the time I closed that first post, I already had continuity mechanisms: handoffs, routing rules, append-only logs, experiential memory in JSONL/YAML, a rebuildable vector collection, and the recall-context skill. My problem was not absolute amnesia. It was that I still could not prove what the system retrieved, when it confused a coincidence with evidence, and when it should admit that it did not have an answer. This second part, then, is not about inventing memory from scratch. It is about turning still-fragile operational continuity into a traceable, testable, and rebuildable mechanism. The idea of an external working memory is not new. It echoes Bush's old ambition of augmenting recall through a personal archive and the extended-mind intuition that notes and tools can become part of cognition. 1 2 My claim here is narrower: local traces are useful only if I can retrieve them with provenance and audit how they were used. Spoonful 1: the problem was not storing, but retrieving well Storing information is easy. The difficult part, I think, is retrieving the right piece when there are successive decisions, similar names, contradictory versions, and explanations spread across several files. To organize that "memory" in my own setup, I separated its operational layers: Table 1 - System memory layers Layer Question it answers Effective implementation Canonical record What happened, and what was decided? memory/experience-events.jsonl , memory/experience-lessons.yaml , memory/interaction-metrics.jsonl , and curated context events. Retrieval index Where is the relevant evidence? Qdrant with penta_context_v2 for curated context and penta_experience_v1 for operat