Skip to main content

Each record is a folder, called a bundle, under agent-qa-knowledge/memory/<product>/bundles/<record-id>/. The fact, the evidence for it and where it came from travel together.

Files in a record

FileCommittedWhat it holds
record.mdYesThe record itself: identity in the frontmatter, then a summary and a detail section.
evidence/outcomes.jsonlYesThe append-only log of outcomes. Trust and status are worked out from it.
provenance.jsonYesWhere the record came from: the run, the step, and how it was written.
observations.jsonlYesThe structured evidence the record was distilled from.
relations.jsonYesLinks to other records, such as supersedes or conflicts-with.
manifest.jsonYesContent hashes of every file, used to check the record has not been altered.
evidence/evidence.mdYesThe distilled observations, written out for people.
evidence/gates.jsonlYesResults of the checks the record passed, when it has any.
evidence/measurements.jsonYesThe baseline for a numeric measurement.
artifacts.index.jsonYesA list of the screenshots and snapshots the record points to.
artifacts/NoThe screenshots and page snapshots themselves.

An example

---
schemaVersion: 2
id: "fact-el-button-place-order-36-00-dd75ab371443d7b6"
kind: "fact"
subtype: "behavioral"
anchors: [{"raw":{"t":"el","role":"button","name":"place order · $36.00","ordinal":0},"normalized":{"t":"el","role":"button","name":"place order · $36.00","ordinal":0}},{"raw":{"t":"platform","platform":"web"},"normalized":{"t":"platform","platform":"web"}}]
scope: {"tier":"product","key":"komazon"}
createdAtOrdinal: 1
originClass: "agent-verified"
evidenceIncomplete: false
---

## Summary

button "place order · $36.00" resolved as a verified element

## Detail

Verified button "place order · $36.00" from the recorded screen state.

Three runs later, its outcome log holds three confirmations:

{"buildOrdinal":1,"origin":"agent-verified","type":"confirmed", …}
{"buildOrdinal":3,"origin":"agent-verified","type":"confirmed", …}
{"buildOrdinal":5,"origin":"agent-verified","type":"confirmed", …}

The frontmatter holds identity only. Trust, status and counters are never written into record.md; they are worked out from the log each time the record is read.

Kinds

KindMeaningCan become active
factSomething true about the app. Subtypes: selector, behavioral, navigational, measurement.Yes
cautionA known failure mode, learned from a test whose root cause was a timeout, a flaky failure or the environment.Yes
procedureA flow that passed end to end, with typed parameters, stored as a replayable list of actions.No, it is served by a separate matcher
unknownAn open question, such as an anchor whose facts keep changing. Never served as a hint.No
policyA QA rule held as a record. Accepting it appends the rule to your policies.No

Status

StatusMeaning
candidateRecorded, not yet promoted. Every record starts here.
activePromoted. Served as a normal hint.
supersededReplaced by a newer record. Kept for history.
deprecatedRetired, rejected or forgotten. Kept as a tombstone.

Nothing is deleted when a record changes status. agent-qa does clean up long chains: it keeps the three most recent superseded generations of a record and removes older ones, never touching records that came from you. That cleanup shows up in git status.

Trust

Trust is a number between 0 and 1, worked out from the outcome log:

trust = (confirmed + ¼·helpful + α) / (confirmed + ¼·helpful + contradicted + ¼·harmful + α + β)

The starting values α and β depend on where the record came from:

OriginαβTrust after one confirmation
user: a person, through a mark or a review310.80
agent-verified: learned from a run210.75

A record that later runs stop confirming fades. After 5 runs without a confirmation (3 for measurements) its trust is multiplied by 0.6 when it is served, and the brief notes unconfirmed since build N.

Scope

A record's scope says where it applies: global, product, suite or test. In v0.2 everything agent-qa learns is scoped to the product of the run's target. A product is the target's product field, or the target name when it has none, and it also names the record's folder.

A run is served records from the global scope, its own product, the suite it runs in and the test itself. Sibling suites and tests never see each other's records.

Anchors

Anchors tie a record to something concrete in the app. The first anchor is the record's main anchor and part of its ID.

AnchorPoints at
pageA route or URL
flowA named flow, such as a test
elAn element, by role, accessible name and position
platformweb, android or ios, so web and mobile facts stay apart
selectorA literal selector
errorAn error message

Validity

Each record knows the run count at which it was created and, when replaced, the count at which it stopped being true. A run is served a record only inside that window, which is how agent-qa knowledge inspect --as-of-build <n> can show the store as it was.

Relations

relations.json links records: supersedes, superseded-by, derived-from, conflicts-with, relates-to, renamed-from, equivalent-to and proposed-supersession-of. The last one appears when a CI run proposes a replacement without applying it.

Outcome events

The outcome log uses a small, fixed vocabulary: confirmed, contradicted, helpful, harmful, promoted, superseded, deprecated, window-close, retracted and overturned. A rollback appends retracted events that cancel earlier ones, so the history is never rewritten.

IDs and addresses

  • Record ID, such as fact-el-button-place-order-36-00-dd75ab371443d7b6: the kind, a short slug of the main anchor, and a hash of the record's identity. Stable across machines, so use it in commits and conversations.
  • Short ID, such as MEM-001: a handy address assigned the first time a record is listed or resolved on your machine. It is local and never reused. MEM-1 works too.
  • URI, such as agentqa://memory/MEM-001: the same address as an MCP resource.

npx agent-qa entities resolve "place order button" finds a record from free text, and npx agent-qa entities get MEM-001 shows its card.