{"entry":{"fixtureId":"hello-counter-v0","appSlug":"hello-counter","appName":"Hello Counter","reportId":"lab_hello-counter-v0_20260610225855199","generatedAt":"2026-06-10T22:58:55.199Z","status":"pass","jsonPath":"/bundle/server-functions/default/.nocklab/hello-counter.report.json","markdownPath":"/bundle/server-functions/default/.nocklab/hello-counter.report.md","reportHash":"sha256:b633189d4d1e259b631746ad50df53bd41e276003ca80696af5bf3f7947397f4","snapshotRoot":"c88df7375b7c9399","badgeCandidate":{"id":"badge-candidate-hello-counter","label":"Hello Counter Verification Candidate","reportSlug":"hello-counter","fixtureId":"hello-counter-v0","status":"ready","evidenceKind":"model-attested","statusReDerived":"pass","statusConsistent":true,"kernelHash":null,"kernelVerified":false,"baseDeploymentHash":null,"baseVerified":false,"signatureStatus":"unsigned","evidence":{"reportHash":"sha256:b633189d4d1e259b631746ad50df53bd41e276003ca80696af5bf3f7947397f4","snapshotRoot":"c88df7375b7c9399","invariantPacks":[]}},"stepsPassed":4,"stepsTotal":4,"invariantsPassed":4,"invariantsTotal":4,"alertsTriggered":0,"snapshotsCaptured":5,"adapterObservationCount":0,"invariantPackCount":0},"report":{"reportId":"lab_hello-counter-v0_20260610225855199","fixtureId":"hello-counter-v0","generatedAt":"2026-06-10T22:58:55.199Z","app":{"name":"Hello Counter","slug":"hello-counter","version":"0.0.1","kernel":"hoon-counter-v0"},"environment":{"mode":"mock-fakenet","grpcEndpoint":"127.0.0.1:5555","fakenetCommand":"nockchain --fakenet --bind-public-grpc-addr 127.0.0.1:5555 --no-default-peers","notes":["Modeled after the official local fakenet flow.","This fixture is mock-backed until a real adapter can call a node."]},"summary":{"status":"pass","stepsPassed":4,"stepsFailed":0,"invariantsPassed":4,"invariantsFailed":0,"alertsClear":0,"alertsTriggered":0,"snapshotsCaptured":5,"durationMs":68,"expectRejected":false,"rawStatus":"pass"},"invariantPacks":[],"steps":[{"id":"boot-fakenet","type":"fakenet","title":"Boot mock fakenet profile","status":"pass","expectation":"gRPC endpoint configured at 127.0.0.1:5555","observed":"mock-fakenet profile ready at 127.0.0.1:5555","beforeHash":"6c97df081d4232bf","afterHash":"6c97df081d4232bf","stateDiffs":[],"durationMs":19},{"id":"poke-increment-alice","type":"poke","title":"Alice increments counter","status":"pass","actor":"alice","target":"/counter","expectation":"counter == 1","observed":"1","beforeHash":"6c97df081d4232bf","afterHash":"dd14a89292afeb15","stateDiffs":[{"path":"counter","before":"0","after":"1"}],"durationMs":26},{"id":"poke-increment-bob","type":"poke","title":"Bob increments counter and receives test balance","status":"pass","actor":"bob","target":"/counter","expectation":"counter == 2","observed":"2","beforeHash":"dd14a89292afeb15","afterHash":"c88df7375b7c9399","stateDiffs":[{"path":"counter","before":"1","after":"2"},{"path":"balances.alice","before":"1000","after":"700"},{"path":"balances.bob","before":"0","after":"300"}],"durationMs":33},{"id":"peek-counter","type":"peek","title":"Read counter value","status":"pass","target":"/counter","expectation":"counter == 2","observed":"2","beforeHash":"c88df7375b7c9399","afterHash":"c88df7375b7c9399","stateDiffs":[],"durationMs":40}],"invariants":[{"id":"counter-non-negative","title":"Counter is never negative","severity":"critical","status":"pass","observed":"2","expected":"counter >= 0"},{"id":"counter-final-value","title":"Counter final value matches fixture","severity":"medium","status":"pass","observed":"2","expected":"counter == 2"},{"id":"poke-actors-declared","title":"Every poke has a declared actor","severity":"high","status":"pass","observed":"2/2 poke steps declared actors","expected":"all poke steps declare actors"},{"id":"supply-conserved","title":"NOCK-denominated balances conserve supply","severity":"critical","status":"pass","observed":"total=1000, supply=1000","expected":"balances sum equals totalSupply"}],"alerts":[],"adapterObservations":[],"stateSnapshots":[{"label":"Initial state","stateHash":"6c97df081d4232bf","state":{"counter":0,"totalSupply":1000,"balances":{"alice":1000,"bob":0}}},{"label":"After boot-fakenet","stateHash":"6c97df081d4232bf","state":{"counter":0,"totalSupply":1000,"balances":{"alice":1000,"bob":0}},"stepId":"boot-fakenet"},{"label":"After poke-increment-alice","stateHash":"dd14a89292afeb15","state":{"counter":1,"totalSupply":1000,"balances":{"alice":1000,"bob":0}},"stepId":"poke-increment-alice"},{"label":"After poke-increment-bob","stateHash":"c88df7375b7c9399","state":{"counter":2,"totalSupply":1000,"balances":{"alice":700,"bob":300}},"stepId":"poke-increment-bob"},{"label":"After peek-counter","stateHash":"c88df7375b7c9399","state":{"counter":2,"totalSupply":1000,"balances":{"alice":700,"bob":300}},"stepId":"peek-counter"}],"stateDiffs":[{"path":"counter","before":"0","after":"2"},{"path":"balances.alice","before":"1000","after":"700"},{"path":"balances.bob","before":"0","after":"300"}],"nextActions":["Replace mock poke and peek execution with local fakenet adapter calls.","Replace command-backed fakenet metadata probes with stable gRPC-native probes once node surfaces are available.","Persist generated reports under a project workspace.","Add app-specific invariant packs as the NockApp interface stabilizes."]},"markdown":"# ✅ Hello Counter Lab Report\n\n> **PASS** — 4/4 steps · 4/4 invariants · 0 alerts · 68ms\n\n| Field | Value |\n| --- | --- |\n| Report | `lab_hello-counter-v0_20260610225855199` |\n| Fixture | `hello-counter-v0` |\n| Status | ✅ pass |\n| Steps | 4 passed, 0 failed |\n| Invariants | 4 passed, 0 failed |\n| Alerts | 0 clear, 0 triggered |\n| Snapshots | 5 |\n\n## Steps\n\n- ✅ `boot-fakenet` — mock-fakenet profile ready at 127.0.0.1:5555 _(gRPC endpoint configured at 127.0.0.1:5555)_; 6c97df081d4232bf -> 6c97df081d4232bf\n- ✅ `poke-increment-alice` — 1 _(counter == 1)_; 6c97df081d4232bf -> dd14a89292afeb15\n  - counter: 0 -> 1\n- ✅ `poke-increment-bob` — 2 _(counter == 2)_; dd14a89292afeb15 -> c88df7375b7c9399\n  - counter: 1 -> 2\n  - balances.alice: 1000 -> 700\n  - balances.bob: 0 -> 300\n- ✅ `peek-counter` — 2 _(counter == 2)_; c88df7375b7c9399 -> c88df7375b7c9399\n\n## Invariants\n\n- ✅ `counter-non-negative` — 2 _(expected counter >= 0)_\n- ✅ `counter-final-value` — 2 _(expected counter == 2)_\n- ✅ `poke-actors-declared` — 2/2 poke steps declared actors _(expected all poke steps declare actors)_\n- ✅ `supply-conserved` — total=1000, supply=1000 _(expected balances sum equals totalSupply)_\n\n## Alerts\n\n- No alert policies configured.\n\n## Adapter Observations\n\n- No adapter observations captured.\n\n## State Diffs\n\n- counter: 0 -> 2\n- balances.alice: 1000 -> 700\n- balances.bob: 0 -> 300\n\n## Snapshot Timeline\n\n- Initial state: 6c97df081d4232bf\n- After boot-fakenet: 6c97df081d4232bf\n- After poke-increment-alice: dd14a89292afeb15\n- After poke-increment-bob: c88df7375b7c9399\n- After peek-counter: c88df7375b7c9399\n\n","evidence":{"stateDiffCount":3,"snapshotCount":5,"alertCount":0,"triggeredAlertCount":0,"clearAlertCount":0,"triggeredCriticalAlertCount":0,"triggeredWarningAlertCount":0,"triggeredInfoAlertCount":0,"environmentMode":"mock-fakenet","grpcEndpoint":"127.0.0.1:5555","environmentNoteCount":2,"nextActionCount":4,"firstNextAction":"Replace mock poke and peek execution with local fakenet adapter calls.","invariantPackCount":0,"invariantPackIds":[],"invariantPackDomains":[],"firstInvariantPackPath":"","changedPaths":["counter","balances.alice","balances.bob"],"markdownPreview":"# ✅ Hello Counter Lab Report"}}