signal-ingest — observed behaviour as evidence, never as an answer
Follow the shared contract in ../README.md.
need-understanding raises the ambiguities a requirement leaves open, and openapi-ingest raises
the ones a specification leaves open: is limit bounded?, which status does a duplicate
registration return?. Both hand those questions to a human, who then arbitrates them blind — while
the running system answers them a thousand times a day and nobody writes it down.
This skill closes that gap without ever deciding anything. It attaches observed evidence to an
existing question so the human who arbitrates it stops arbitrating blind.
The line this skill does not cross
It reads a file the user exports and hands over. It never connects to anything. No endpoint,
no credential, no APM token, no log stream, no polling. The project's scope decision keeps
production monitoring out; ingesting an artefact someone chose to export is the same shape as
traffic-replay reading a HAR, and stays inside it.
If asked to fetch the data itself, refuse and say what to export instead.
Accepted inputs
| Input |
What is extracted |
| access-log extract |
path, method, status, count |
| status-code breakdown (CSV/JSON) |
path × status frequency |
| error-rate or APM export |
error class, endpoint, frequency, first/last seen |
| HAR capture |
request/response pairs — hand to traffic-replay for test generation, here only for evidence |
| a table pasted by the user |
whatever it actually contains, and nothing inferred |
Anything else: say it is not supported rather than guessing at a format.
The rule that makes it honest
Observed is not specified. Traffic shows what the system does, under the load and the
population it happened to see. It never shows what the system must do. A signal is therefore
always recorded as "observed X over period P, N occurrences" — never as "the answer to Q3 is X".
Three ways an observation misleads, to be stated whenever they apply:
- Absence proves nothing. No 409 in 30 days may mean the case cannot occur, or that the client
prevents it, or that the export was filtered. Never write "the 409 is dead code".
- A maximum is not a bound. The largest
limit ever seen was 100; that says nothing about what
the server accepts, only about what clients asked for.
- Production is not the population. Whatever the sample under-represents — a locale, a role, a
device — is exactly where the untested behaviour lives.
Steps
Take the artefact and freeze it. Copy it into the run's sources/, record its sha256 and
the period it covers. An evidence file whose provenance cannot be re-read is an opinion.
Take the open questions. Read the # open: Qn entries in the test book. No open
questions, no work — say so and stop. This skill informs existing questions; it does not
invent new ones from data, which would be reading tea leaves.
Aggregate by operation, never by path alone. GET /articles and POST /articles are two
different promises sharing a string. The first run of this skill collapsed them and reported a
single 422 count that was in fact two unrelated findings — eight rejections of an oversized
limit on the read, and forty-one body-validation failures on the write. Method, path and
status together, always.
Match evidence to questions, conservatively. A signal attaches to a question only when it
speaks to the same endpoint, field or status. When it does not, leave the question untouched:
an unrelated fact attached to a question makes the question harder to answer, not easier.
Write the evidence next to the question, never in place of it. The question stays # open.
# open: Q3 — is `limit` bounded above?
# evidence (signal-ingest, <period start>..<period end>, access-log.csv sha256 a1b2…):
# max observed value 100 over 41 812 requests; 3 responses 422 above it.
# Observed only — does not establish the specified bound.
Report what the evidence did NOT reach. List the open questions no signal informed. That
list is the real output: it is the set of things production cannot tell you, and it is where
human arbitration is genuinely required.
Hand durable findings to rag-build. A recurring observed behaviour is a candidate entry
for knowledge/application-map.md, with its provenance and its period. One-offs stay in the
run.
What this skill must refuse
- Closing an open question. It attaches evidence; a human decides. Not overridable by "the data
is obvious".
- Connecting to anything. No fetch, no credential, no live endpoint — the user exports, this
reads.
- Inventing questions from data. Without an existing
# open: Qn, there is nothing to inform.
- Treating absence as a negative. "Never observed" is recorded as never observed, with the
period and the sample size, and never as "does not happen".
- Ingesting raw personal data. Access logs carry IPs, user IDs, tokens and emails. Mask before
writing anything, exactly as
us-ingest does, and never persist a mapping from the original
value to its placeholder.
- Generating tests directly. Evidence feeds design;
traffic-replay is the skill that turns
captured traffic into tests, and the two must not be merged.
1---2name: signal-ingest3description: Ingest an exported production signal - an access-log extract, an error-rate table, a status-code breakdown, an APM export or a HAR capture - and attach it as evidence to the open questions a test book already carries. Answers nothing on its own - it turns a blind open question into an informed one. Use when a test book has open questions that observed behaviour could inform, or when production data exists and nobody has connected it to the test design.4---56# signal-ingest — observed behaviour as evidence, never as an answer78Follow the shared contract in `../README.md`.910`need-understanding` raises the ambiguities a requirement leaves open, and `openapi-ingest` raises11the ones a specification leaves open: *is `limit` bounded?*, *which status does a duplicate12registration return?*. Both hand those questions to a human, who then arbitrates them blind — while13the running system answers them a thousand times a day and nobody writes it down.1415This skill closes that gap **without ever deciding anything**. It attaches observed evidence to an16existing question so the human who arbitrates it stops arbitrating blind.1718## The line this skill does not cross1920**It reads a file the user exports and hands over. It never connects to anything.** No endpoint,21no credential, no APM token, no log stream, no polling. The project's scope decision keeps22production *monitoring* out; ingesting an artefact someone chose to export is the same shape as23`traffic-replay` reading a HAR, and stays inside it.2425If asked to fetch the data itself, refuse and say what to export instead.2627## Accepted inputs2829| Input | What is extracted |30|---|---|31| access-log extract | path, method, status, count |32| status-code breakdown (CSV/JSON) | path × status frequency |33| error-rate or APM export | error class, endpoint, frequency, first/last seen |34| HAR capture | request/response pairs — hand to `traffic-replay` for test generation, here only for evidence |35| a table pasted by the user | whatever it actually contains, and nothing inferred |3637Anything else: say it is not supported rather than guessing at a format.3839## The rule that makes it honest4041**Observed is not specified.** Traffic shows what the system *does*, under the load and the42population it happened to see. It never shows what the system *must* do. A signal is therefore43always recorded as *"observed X over period P, N occurrences"* — never as *"the answer to Q3 is X"*.4445Three ways an observation misleads, to be stated whenever they apply:4647- **Absence proves nothing.** No 409 in 30 days may mean the case cannot occur, or that the client48 prevents it, or that the export was filtered. Never write "the 409 is dead code".49- **A maximum is not a bound.** The largest `limit` ever seen was 100; that says nothing about what50 the server accepts, only about what clients asked for.51- **Production is not the population.** Whatever the sample under-represents — a locale, a role, a52 device — is exactly where the untested behaviour lives.5354## Steps55561. **Take the artefact and freeze it.** Copy it into the run's `sources/`, record its sha256 and57 the period it covers. An evidence file whose provenance cannot be re-read is an opinion.58592. **Take the open questions.** Read the `# open: Qn` entries in the test book. **No open60 questions, no work** — say so and stop. This skill informs existing questions; it does not61 invent new ones from data, which would be reading tea leaves.62633. **Aggregate by operation, never by path alone.** `GET /articles` and `POST /articles` are two64 different promises sharing a string. The first run of this skill collapsed them and reported a65 single 422 count that was in fact two unrelated findings — eight rejections of an oversized66 `limit` on the read, and forty-one body-validation failures on the write. Method, path and67 status together, always.68694. **Match evidence to questions, conservatively.** A signal attaches to a question only when it70 speaks to the same endpoint, field or status. When it does not, leave the question untouched:71 an unrelated fact attached to a question makes the question harder to answer, not easier.72735. **Write the evidence next to the question, never in place of it.** The question stays `# open`.7475 ```76 # open: Q3 — is `limit` bounded above?77 # evidence (signal-ingest, <period start>..<period end>, access-log.csv sha256 a1b2…):78 # max observed value 100 over 41 812 requests; 3 responses 422 above it.79 # Observed only — does not establish the specified bound.80 ```81826. **Report what the evidence did NOT reach.** List the open questions no signal informed. That83 list is the real output: it is the set of things production cannot tell you, and it is where84 human arbitration is genuinely required.85867. **Hand durable findings to `rag-build`.** A recurring observed behaviour is a candidate entry87 for `knowledge/application-map.md`, with its provenance and its period. One-offs stay in the88 run.8990## What this skill must refuse9192- **Closing an open question.** It attaches evidence; a human decides. Not overridable by "the data93 is obvious".94- **Connecting to anything.** No fetch, no credential, no live endpoint — the user exports, this95 reads.96- **Inventing questions from data.** Without an existing `# open: Qn`, there is nothing to inform.97- **Treating absence as a negative.** "Never observed" is recorded as never observed, with the98 period and the sample size, and never as "does not happen".99- **Ingesting raw personal data.** Access logs carry IPs, user IDs, tokens and emails. Mask before100 writing anything, exactly as `us-ingest` does, and never persist a mapping from the original101 value to its placeholder.102- **Generating tests directly.** Evidence feeds design; `traffic-replay` is the skill that turns103 captured traffic into tests, and the two must not be merged.