Tines Monitor live trial, 26 September 2026
The Monitor example story acts at a vendor with its own credential and reports each result, and a scheduled heartbeat, to ExecBound's monitoring intake. This trial ran it in a real Tines tenant against a local monitoring service: success, error and unknown results, a duplicate retry, scheduled heartbeats, a heartbeat stopped until the source read stale and then resumed, an unreachable intake and its recovery, token rotation inside and past the grace window, collection coverage of the tenant, and a revoked source. Every finding was delivered to the authenticated loopback receiver.
Host: a Tines Community Edition lab tenant; the trial story "ExecBound: Monitor an action (example)", id 147205, imported through the Tines API from the committed integrations/tines/execbound-monitor.json and deleted afterwards, with its two credentials and two resources
Version: Tines export schema 30, standard library 97, action runtime 88 (the tenant's own export fields); ExecBound 0.1.0, monitor events v1
Date: 2026-09-26 UTC, 00:24 to 01:02
Transport: Tines HTTP Request actions to the intake-only origin (execbound.monitoring.ingress, loopback 8622) and to a loopback lab vendor stub (loopback 8623) kept with the trial's private evidence, each behind a Cloudflare quick tunnel run only for the trial; the monitoring service on loopback 8620 and the loopback alert receiver on 8621 were never exposed
Gateway commit: 88c5ded (main at the start of the trial). The trial changed no server code; the story changed once during the trial, below
Fixture seed: init-demo on a local database, a synthetic tenant with an eight-hour ADMIN credential; its synthetic lab-story source was revoked before the trial so it could not age into a finding. The story's source e350211b-c956-47f7-a5b2-efbb40b40e5a was registered with create-source --story-id 147205 --hours 12, heartbeat interval 300 seconds. No hosted database, hosted gateway or real vendor was used
One live fix
The first two reports, a result at 00:29 and the scheduled heartbeat at 00:30, were both refused
400 INVALID_EVENT, and both runs took Reporting failed with reason: not_recorded and the
code. The bodies Tines built were correct. The requests were sent with content_type: json,
and Tines' JSON "smart validation" sends a digit-only string as a number, so the story id
"147205" arrived as 147205, which the strict intake refuses. The same trap is recorded for
text templates from the 14 September trial; this trial shows a formula object does not avoid
it. The story was changed to send =TO_JSON(...) text with the explicit
Content-Type: application/json header and no content_type. The live actions were updated in
place from the regenerated file and checked action by action against it. Every later report
was accepted.
The cause was then confirmed directly. The vendor action was set back to content_type: json
for one run, with the target 12345. The stub received a non-string target and answered 400.
Restored to the committed form, the target 67890 arrived as a string and was answered 200.
Both runs reported, as error and success.
At the time of this trial the Execute and Gate stories still sent content_type: json, and the
gateway's strict parser refuses a numeric reference or target value, so a digit-only ticket
number or provider id sent through either story would have been refused. Both stories were
changed on 30 September 2026 to send TO_JSON text with an explicit header, as
their guide describes.
Scenarios
Import. The committed file imported through POST /api/v1/stories/import as story 147205.
Its export matched the committed file action for action, including every option, the
heartbeat's */5 * * * * schedule and the links. The webhook's path and secret, blank in the
file, were set through the API. The story was disabled straight after import and enabled only
once the source, credentials and resources existed.
Success (target lab-ws-01, Tines run 2f48135b-1a99-427f-a098-8c3a393ef42b, 00:30:33):
vendor 200, report 202, observation 614d43e8-ab0c-534a-9d38-8af5c5ef4a8e with event_id
tines-147205-1348829066 and outcome success. Evaluation matched sensitive-action.v2 and finding
50d4e3d1-264a-57c1-b791-47daa47a0d32 was delivered on the first attempt.
Error (fail-ws-02, 00:30:55): vendor 503, observation 90e9cf6c-… with outcome error, a
sensitive-action.v2 finding delivered. The action was not retried.
Unknown (hang-ws-03, 00:31:26): the stub held the request for 45 seconds. Tines gave up at
thirty seconds and, because emit_failure_event is on, emitted status 0. The observation
0fa00d18-… records unknown, and a finding was delivered. The stub's own log shows it
answered 200 fifteen seconds after Tines stopped waiting: an effect the story could not know
about, which is what unknown is for.
Retry (00:32:28): the success run's Build result event was re-emitted through the Tines
API. The report sent identical text and was answered 200 with duplicate: true and the same
observation id; the story exited Reported with duplicate. No new observation, finding or
delivery followed.
Heartbeat. Scheduled heartbeats were recorded at 00:35, 00:40 and 00:45, each with its
per-minute event_id (hb-147205-20260926T0035 and so on) and outcome NO_MATCH. The source
read REPORTING.
Intake down (lab-ws-04, 00:35:58). The intake-only origin was stopped with the tunnel
left up. The report retried for about two minutes and then took Reporting failed with
reason: unreachable, status 0. The origin was restarted and the run's Build result event
re-emitted: the report was answered 202, a new observation, which shows none of the failed
attempts had reached the intake.
Rotation (00:38:37). rotate-source --grace-minutes 2 issued a new token while the Tines
credential still held the old one. A result at 00:38:40 and the 00:40 heartbeat were both
accepted inside the grace window. At 00:40:53, past it, the old token was refused 401
INVALID_SOURCE and the story took Reporting failed with reason: auth_lost; the intake
counted one authentication failure with reason MISMATCH. The Tines credential was updated
with the new token and the refused run's event re-emitted; it was recorded 202.
Collection coverage (00:41:56). A read-only collection connection ran one inventory
collection of the tenant: stories, actions and credentials available, audit and AI audit
unsupported on this plan; four stories, 39 actions and five credentials. The trial story was
instrumented. "ExecBound: govern an action", which has an outbound action and no source, was
discovered_only with one instrumentation-gap.v1 finding. "ExecBound: AI Agents" was
coverage_unknown, because its AI agent action type is in neither the outbound nor the local
list, and the disabled smoke test story was disabled.
Heartbeat stopped (00:45:10). The Heartbeat action alone was disabled after the 00:45
heartbeat was recorded, and nothing else was sent. The evaluation at 00:55:42, a little over
two intervals after the last heartbeat at 00:45:07, set the source STALE and recorded one
source-health.v1 finding, "Source stopped reporting", which was delivered.
Resumed (00:56:31). The action was re-enabled. The 01:00 heartbeat was recorded, and the
next evaluation, at 01:00:24, set the source back to REPORTING with no finding and nothing to
deliver.
Auth lost (01:00:32). The source was revoked. The next result, lab-ws-07, was refused 401
INVALID_SOURCE and the story took Reporting failed with reason: auth_lost; the intake
counted one failure with reason REVOKED.
Totals
Twelve observations: eight results and four heartbeats. Ten findings: eight
sensitive-action.v2, one instrumentation-gap.v1, one source-health.v1. Ten deliveries, all
DELIVERED on the first attempt, and ten receiver files, each written only after its
HMAC-SHA256 signature verified and each naming the finding its delivery carried. The lab
vendor received ten requests from Tines. Eight became observations; the other two are the
00:29 result refused before the fix and the result sent after revocation, and both of those
runs exited Reporting failed naming why. Every identifier, state, status, code and time is in
the accompanying JSON.
What this qualifies
The Monitor path from a real Tines story: reporting results and heartbeats with a source token held in a host-restricted Tines credential, the outcome mapping from the story's own HTTP result, idempotent retry, source freshness in both directions, finding evaluation and signed delivery, rotation with a grace window, revocation, and coverage of the tenant against its registered sources. The manifest promotes the Tines instrumented-stories row to Monitor / Observed / platform-validated for these cases.
Not established
- Alert delivery beyond the loopback receiver. Findings reach email, Slack, Teams or an
HTTPS webhook nowhere, and the scheduled
monitor-processjob evaluates without delivering. Delivery was proved only to the authenticated local receiver. - Ongoing operation. The trial ran for about forty minutes. Sources are issued from the command line for at most 24 hours, so a story instrumented for longer needs a daily rotation; nothing here exercised that cadence or a hosted intake.
- A real vendor. The vendor was a loopback stub. What the story observed is what the stub answered, and a source-reported result is never a verified effect.
- Conflicting reuse from the story. The story's event ids make a same-id, different-content report hard to produce by design; the 409 path and its integrity finding are covered by the intake's own tests and by TM4's classification, not by a live run.
- Audit-log collection, which this Community Edition tenant's plan does not expose.
Cleanup
The trial story 147205, its credentials execbound_monitor_source and execbound_lab_vendor,
and its resources execbound_monitor_origin and execbound_lab_vendor_origin were deleted. A
throwaway probe story, 147202, imported before the trial to read META and the schedule
export shape, was deleted at 00:25. The tenant's three earlier stories, credentials and
resources were not modified; the only write to them was a no-op description update to the
disabled smoke test story that confirmed the API key could write. The local services, the
stub and both tunnels were stopped. The source was revoked. The private configuration, tokens,
receipts and the stub's token are kept privately, outside version control.