@volter/twin-telegram 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/journeys/customer-life.json +21 -21
- package/dist/journeys/customer-life.outline.md +17 -17
- package/dist/journeys/customer-life.outline.verdict.json +17 -52
- package/dist/journeys/customer-life.verdict.json +24 -98
- package/dist/journeys/decisions.json +49 -13
- package/dist/journeys/demand.json +0 -91
- package/dist/journeys/first-use.json +21 -0
- package/dist/journeys/unreachable.json +1 -1
- package/dist/journeys/vendor-examples.json +14 -6
- package/dist/spec/SOURCE.md +5 -6
- package/dist/spec/patches.json +20 -20
- package/dist/spec/sources.json +15 -0
- package/dist/src/cli.js +1 -1
- package/dist/src/engine/media.d.ts +6 -12
- package/dist/src/engine/media.js +28 -66
- package/dist/src/engine/text.d.ts +0 -7
- package/dist/src/engine/text.js +2 -2
- package/dist/src/index.js +2 -1
- package/dist/src/manifest.js +7 -6
- package/dist/src/semantics/available-methods.js +50 -40
- package/dist/src/semantics/doors.d.ts +0 -1
- package/dist/src/semantics/doors.js +82 -5
- package/dist/src/semantics/shared.d.ts +10 -6
- package/dist/src/semantics/shared.js +29 -8
- package/dist/src/server.js +2 -19
- package/generated/pack-facts.json +10 -0
- package/journeys/customer-life.json +21 -21
- package/journeys/customer-life.outline.md +17 -17
- package/journeys/customer-life.outline.verdict.json +17 -52
- package/journeys/customer-life.verdict.json +24 -98
- package/journeys/decisions.json +49 -13
- package/journeys/demand.json +0 -91
- package/journeys/first-use.json +21 -0
- package/journeys/unreachable.json +1 -1
- package/journeys/vendor-examples.json +14 -6
- package/package.json +12 -9
- package/spec/SOURCE.md +5 -6
- package/spec/patches.json +20 -20
- package/spec/sources.json +15 -0
- package/src/cli.ts +1 -1
- package/src/engine/media.ts +21 -58
- package/src/engine/text.ts +2 -2
- package/src/index.ts +2 -1
- package/src/manifest.ts +7 -6
- package/src/semantics/available-methods.ts +55 -41
- package/src/semantics/doors.ts +74 -8
- package/src/semantics/shared.ts +27 -8
- package/src/server.ts +2 -11
- package/dist/generated/pack-facts.json +0 -53
- package/dist/spec/page-to-openapi.ts +0 -258
- package/spec/page-to-openapi.ts +0 -258
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@ semantics.
|
|
|
7
7
|
## What it serves, and for whom
|
|
8
8
|
|
|
9
9
|
The calls the demand's applications make (`journeys/demand.json`): Volter Harness's Telegram channel (the Chat SDK's
|
|
10
|
-
`@chat-adapter/telegram`, polling)
|
|
10
|
+
`@chat-adapter/telegram`, polling).
|
|
11
11
|
|
|
12
12
|
- A bot reads itself (`getMe`), removes its webhook (`deleteWebhook`) and polls for its updates (`getUpdates`: offset,
|
|
13
13
|
limit, allowed_updates, and a timeout that holds the request until an update arrives, a long poll).
|
|
@@ -48,6 +48,6 @@ host, `api.telegram.org`.
|
|
|
48
48
|
- Editing messages, reactions, inline keyboards and callback queries, stickers, payments, inline mode, games, business
|
|
49
49
|
and passport methods, forum topics, and every other method of the page.
|
|
50
50
|
- A medium sent by an HTTP URL, which Telegram downloads: a World lets the twin reach nothing outside it, so it answers
|
|
51
|
-
as Telegram does for a URL it could not get
|
|
51
|
+
as Telegram does for a URL it could not get.
|
|
52
52
|
- A photo's other sizes (the twin keeps the one it was given), thumbnails, and a video's frames beyond its header.
|
|
53
53
|
- The 3-second hold the server puts on a repeated short poll, and a second poller's conflict.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"vendor": "telegram",
|
|
3
3
|
"author": "Contributor 173",
|
|
4
4
|
"host": "api.telegram.org",
|
|
5
|
-
"about": "Tide Labs, a two-person studio, runs its Volter Harness agent on Telegram (a bot polling for updates, answering in private and in the team group, where privacy mode keeps a plain member from hearing the team until it is made an administrator, posting a scheduled digest, and sending a finished card's release notes as a document) and publishes its news to a Telegram channel through
|
|
5
|
+
"about": "Tide Labs, a two-person studio, runs its Volter Harness agent on Telegram (a bot polling for updates, answering in private and in the team group, where privacy mode keeps a plain member from hearing the team until it is made an administrator, posting a scheduled digest, and sending a finished card's release notes as a document) and publishes its news to a Telegram channel through Scheduler (connected by a /connect post, then text, an album, a reply, a photo, a video and a PDF), from January to the agent's retirement at the end of February.",
|
|
6
6
|
"steps": [
|
|
7
7
|
{
|
|
8
8
|
"name": "Monday 5 January, 10:00 in Lisbon",
|
|
@@ -530,7 +530,7 @@
|
|
|
530
530
|
]
|
|
531
531
|
},
|
|
532
532
|
{
|
|
533
|
-
"name": "Ana makes the news bot with BotFather for
|
|
533
|
+
"name": "Ana makes the news bot with BotFather for Scheduler, which she runs herself (docker compose, local storage)",
|
|
534
534
|
"method": "POST",
|
|
535
535
|
"path": "/_twin/bots",
|
|
536
536
|
"body": {
|
|
@@ -571,11 +571,11 @@
|
|
|
571
571
|
]
|
|
572
572
|
},
|
|
573
573
|
{
|
|
574
|
-
"name": "14:06: Ana sets her
|
|
574
|
+
"name": "14:06: Ana sets her Scheduler's TELEGRAM_TOKEN to the news bot's token and, in Scheduler, chooses to add Telegram",
|
|
575
575
|
"wait": "1m"
|
|
576
576
|
},
|
|
577
577
|
{
|
|
578
|
-
"name": "
|
|
578
|
+
"name": "Scheduler's connect screen polls the news bot: only the bot's own promotion is waiting, and it holds no /connect",
|
|
579
579
|
"method": "POST",
|
|
580
580
|
"path": "/bot{news_token}/getUpdates",
|
|
581
581
|
"headers": {
|
|
@@ -602,7 +602,7 @@
|
|
|
602
602
|
]
|
|
603
603
|
},
|
|
604
604
|
{
|
|
605
|
-
"name": "Ana posts the command
|
|
605
|
+
"name": "Ana posts the command Scheduler shows her in the channel",
|
|
606
606
|
"method": "POST",
|
|
607
607
|
"path": "/_twin/messages",
|
|
608
608
|
"body": {
|
|
@@ -613,7 +613,7 @@
|
|
|
613
613
|
"status": 200
|
|
614
614
|
},
|
|
615
615
|
{
|
|
616
|
-
"name": "
|
|
616
|
+
"name": "Scheduler polls again from the next update (the last update_id it saw plus one) and finds the /connect post",
|
|
617
617
|
"method": "POST",
|
|
618
618
|
"path": "/bot{news_token}/getUpdates",
|
|
619
619
|
"headers": {
|
|
@@ -637,7 +637,7 @@
|
|
|
637
637
|
]
|
|
638
638
|
},
|
|
639
639
|
{
|
|
640
|
-
"name": "
|
|
640
|
+
"name": "Scheduler reads its bot",
|
|
641
641
|
"method": "POST",
|
|
642
642
|
"path": "/bot{news_token}/getMe",
|
|
643
643
|
"headers": {
|
|
@@ -709,7 +709,7 @@
|
|
|
709
709
|
"wait": "10s"
|
|
710
710
|
},
|
|
711
711
|
{
|
|
712
|
-
"name": "
|
|
712
|
+
"name": "Scheduler deletes its notice",
|
|
713
713
|
"method": "POST",
|
|
714
714
|
"path": "/bot{news_token}/deleteMessage",
|
|
715
715
|
"headers": {
|
|
@@ -725,7 +725,7 @@
|
|
|
725
725
|
]
|
|
726
726
|
},
|
|
727
727
|
{
|
|
728
|
-
"name": "
|
|
728
|
+
"name": "Scheduler reads the channel it is connecting",
|
|
729
729
|
"method": "POST",
|
|
730
730
|
"path": "/bot{news_token}/getChat",
|
|
731
731
|
"headers": {
|
|
@@ -783,7 +783,7 @@
|
|
|
783
783
|
"wait": "71630s"
|
|
784
784
|
},
|
|
785
785
|
{
|
|
786
|
-
"name": "
|
|
786
|
+
"name": "Scheduler publishes the launch post (Scheduler's HTML: a bold title, two paragraphs)",
|
|
787
787
|
"method": "POST",
|
|
788
788
|
"path": "/bot{news_token}/sendMessage",
|
|
789
789
|
"headers": {
|
|
@@ -944,7 +944,7 @@
|
|
|
944
944
|
"wait": "67h"
|
|
945
945
|
},
|
|
946
946
|
{
|
|
947
|
-
"name": "
|
|
947
|
+
"name": "Scheduler publishes the 0.9 release with three screenshots as one album, the text on the first",
|
|
948
948
|
"method": "POST",
|
|
949
949
|
"path": "/bot{news_token}/sendMediaGroup?chat_id={channel}&media=%5B%7B%22type%22%3A%22photo%22%2C%22media%22%3A%22attach%3A%2F%2F0%22%2C%22caption%22%3A%22%3Cb%3ETide%200.9%3C%2Fb%3E%5CnA%20dashboard%20for%20every%20release%2C%20a%20timeline%20you%20can%20drag%2C%20and%20settings%20in%20one%20place.%22%2C%22parse_mode%22%3A%22HTML%22%7D%2C%7B%22type%22%3A%22photo%22%2C%22media%22%3A%22attach%3A%2F%2F1%22%2C%22parse_mode%22%3A%22HTML%22%7D%2C%7B%22type%22%3A%22photo%22%2C%22media%22%3A%22attach%3A%2F%2F2%22%2C%22parse_mode%22%3A%22HTML%22%7D%5D",
|
|
950
950
|
"form": {
|
|
@@ -979,11 +979,11 @@
|
|
|
979
979
|
"equals": "Tide 0.9\nA dashboard for every release, a timeline you can drag, and settings in one place."
|
|
980
980
|
},
|
|
981
981
|
{
|
|
982
|
-
"path": "result.0.photo.
|
|
982
|
+
"path": "result.0.photo.2.width",
|
|
983
983
|
"equals": 480
|
|
984
984
|
},
|
|
985
985
|
{
|
|
986
|
-
"path": "result.2.photo.
|
|
986
|
+
"path": "result.2.photo.2.height",
|
|
987
987
|
"equals": 300
|
|
988
988
|
},
|
|
989
989
|
{
|
|
@@ -1001,13 +1001,13 @@
|
|
|
1001
1001
|
"wait": "1h"
|
|
1002
1002
|
},
|
|
1003
1003
|
{
|
|
1004
|
-
"name": "
|
|
1004
|
+
"name": "Scheduler publishes the post's comment, the changelog, as a reply to the album",
|
|
1005
1005
|
"method": "POST",
|
|
1006
1006
|
"path": "/bot{news_token}/sendMessage",
|
|
1007
1007
|
"headers": {
|
|
1008
1008
|
"content-type": "application/x-www-form-urlencoded"
|
|
1009
1009
|
},
|
|
1010
|
-
"body": "chat_id={channel}&text=Changelog%3A%20drag%20to%20reschedule%20a%20release%3B%20faster%20dashboard%3B%20fixed%20the%20login%20redirect.%0A&parse_mode=HTML&
|
|
1010
|
+
"body": "chat_id={channel}&text=Changelog%3A%20drag%20to%20reschedule%20a%20release%3B%20faster%20dashboard%3B%20fixed%20the%20login%20redirect.%0A&parse_mode=HTML&reply_parameters=%7B%22message_id%22%3A{album}%7D",
|
|
1011
1011
|
"status": 200,
|
|
1012
1012
|
"expect": [
|
|
1013
1013
|
{
|
|
@@ -1062,7 +1062,7 @@
|
|
|
1062
1062
|
"wait": "1845m"
|
|
1063
1063
|
},
|
|
1064
1064
|
{
|
|
1065
|
-
"name": "
|
|
1065
|
+
"name": "Scheduler sends Ana's product photo with its 1,091-character story, and Telegram refuses the caption",
|
|
1066
1066
|
"method": "POST",
|
|
1067
1067
|
"path": "/bot{news_token}/sendPhoto?chat_id={channel}&caption=Tide%20Desk%20started%20as%20a%20sketch%20on%20a%20caf%C3%A9%20napkin%20in%20Porto%2C%20the%20week%20our%20second%20release%20slipped%20for%20the%20third%20time.%20We%20were%20two%20people%20with%20a%20shared%20spreadsheet%2C%20a%20calendar%20nobody%20trusted%20and%20a%20habit%20of%20shipping%20on%20Fridays%20at%20midnight.%20Ana%20drew%20three%20columns%3A%20what%20is%20ready%2C%20what%20is%20waiting%2C%20what%20is%20promised.%20Bruno%20added%20a%20fourth%3A%20who%20is%20waiting%20for%20it.%20That%20napkin%20became%20the%20first%20board%2C%20and%20the%20board%20became%20the%20planner%20we%20use%20every%20Monday.%20We%20kept%20the%20rule%20from%20that%20night%3A%20nothing%20goes%20on%20the%20timeline%20unless%20someone%20can%20say%20who%20is%20waiting%20for%20it.%20It%20sounds%20small%2C%20but%20it%20changed%20how%20we%20talk%20about%20releases.%20We%20stopped%20arguing%20about%20dates%20and%20started%20asking%20who%20would%20notice.%20The%20desk%20in%20the%20photo%20is%20where%20it%20all%20happens%20now%3A%20one%20screen%20for%20the%20timeline%2C%20one%20for%20the%20changelog%2C%20and%20a%20cup%20that%20says%20Friday.%20Today%20Tide%20plans%20the%20weekly%20releases%20of%20forty%20small%20teams%2C%20from%20a%20bakery%27s%20ordering%20app%20in%20Braga%20to%20a%20school%20timetable%20in%20Coimbra.%20If%20your%20team%20still%20keeps%20its%20releases%20in%20a%20spreadsheet%2C%20we%20were%20you%20two%20years%20ago.%20Come%20and%20try%20the%20board%3B%20the%20napkin%20is%20framed%20on%20the%20wall%20behind%20it.&parse_mode=HTML",
|
|
1068
1068
|
"form": {
|
|
@@ -1092,7 +1092,7 @@
|
|
|
1092
1092
|
"wait": "20m"
|
|
1093
1093
|
},
|
|
1094
1094
|
{
|
|
1095
|
-
"name": "
|
|
1095
|
+
"name": "Scheduler sends the photo again with the short caption",
|
|
1096
1096
|
"method": "POST",
|
|
1097
1097
|
"path": "/bot{news_token}/sendPhoto?chat_id={channel}&caption=Tide%20Desk%20started%20as%20a%20sketch%20on%20a%20caf%C3%A9%20napkin%20in%20Porto%2C%20the%20week%20our%20second%20release%20slipped%20for%20the%20third%20time.%20That%20napkin%20became%20the%20first%20board%2C%20and%20the%20board%20became%20the%20planner%20we%20use%20every%20Monday.%20Today%20Tide%20plans%20the%20weekly%20releases%20of%20forty%20small%20teams.&parse_mode=HTML",
|
|
1098
1098
|
"form": {
|
|
@@ -1108,11 +1108,11 @@
|
|
|
1108
1108
|
"status": 200,
|
|
1109
1109
|
"expect": [
|
|
1110
1110
|
{
|
|
1111
|
-
"path": "result.photo.
|
|
1111
|
+
"path": "result.photo.2.width",
|
|
1112
1112
|
"equals": 640
|
|
1113
1113
|
},
|
|
1114
1114
|
{
|
|
1115
|
-
"path": "result.photo.
|
|
1115
|
+
"path": "result.photo.2.height",
|
|
1116
1116
|
"equals": 480
|
|
1117
1117
|
},
|
|
1118
1118
|
{
|
|
@@ -1126,7 +1126,7 @@
|
|
|
1126
1126
|
"wait": "6880m"
|
|
1127
1127
|
},
|
|
1128
1128
|
{
|
|
1129
|
-
"name": "
|
|
1129
|
+
"name": "Scheduler publishes the product demo video",
|
|
1130
1130
|
"method": "POST",
|
|
1131
1131
|
"path": "/bot{news_token}/sendVideo?chat_id={channel}&caption=Three%20seconds%20of%20Tide%200.9%3A%20a%20release%20dragged%20to%20Friday.&parse_mode=HTML",
|
|
1132
1132
|
"form": {
|
|
@@ -1164,7 +1164,7 @@
|
|
|
1164
1164
|
"wait": "4h"
|
|
1165
1165
|
},
|
|
1166
1166
|
{
|
|
1167
|
-
"name": "
|
|
1167
|
+
"name": "Scheduler publishes the white paper as a PDF",
|
|
1168
1168
|
"method": "POST",
|
|
1169
1169
|
"path": "/bot{news_token}/sendDocument?chat_id={channel}&caption=How%20a%20two-person%20team%20ships%20every%20week%3A%20our%20notes%2C%20as%20a%20PDF.&parse_mode=HTML",
|
|
1170
1170
|
"form": {
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
**The customer.** Tide Labs, a two-person software studio in Lisbon. Ana Ribeiro, its founder, runs an agent on Volter
|
|
4
4
|
Harness that she and the team talk to on Telegram, and publishes the studio's news to its Telegram channel with
|
|
5
|
-
|
|
6
|
-
2026: two bots made, the agent at work in a private chat and a group, a news channel connected to
|
|
5
|
+
Scheduler. Bruno Costa, its engineer, is on the team chat. The story runs from Monday 5 January to Friday 27 February
|
|
6
|
+
2026: two bots made, the agent at work in a private chat and a group, a news channel connected to Scheduler and posted to
|
|
7
7
|
for six weeks, the agent's group retired and, at the end, the agent's token revoked. The channel and its bot stay.
|
|
8
8
|
|
|
9
9
|
## Who acts, and with what
|
|
@@ -21,8 +21,8 @@ for six weeks, the agent's group retired and, at the end, the agent's token revo
|
|
|
21
21
|
Harness's board, where the agent files work as cards, tells a chat subscribed to a card when it is done, the card's
|
|
22
22
|
files attached; the Chat SDK sends a message with files as MarkdownV2 (supercode board/dispatch.mjs notifyChats,
|
|
23
23
|
@chat-adapter/telegram's resolveParseMode).
|
|
24
|
-
- **The news bot**, @tidelabs_news_bot, token N: the bot
|
|
25
|
-
the one bot its deployment configures, its TELEGRAM_TOKEN
|
|
24
|
+
- **The news bot**, @tidelabs_news_bot, token N: the bot Scheduler posts with. Scheduler's Telegram integration calls with
|
|
25
|
+
the one bot its deployment configures, its TELEGRAM_TOKEN, so Ana runs Scheduler
|
|
26
26
|
herself (docker compose, local storage) and sets its TELEGRAM_TOKEN to token N. She makes the bot an administrator of
|
|
27
27
|
the channel allowed to post and to delete messages.
|
|
28
28
|
|
|
@@ -54,17 +54,17 @@ is a member; a bot deletes another's message in a channel only with the right to
|
|
|
54
54
|
exactly those items to the home chat (sendMessage to the group).
|
|
55
55
|
5. **Wednesday 7 January, 14:00. The news channel.** Ana makes the public channel "Tide Labs News" (@tidelabs_news)
|
|
56
56
|
with the studio's logo as its photo (door). She makes the news bot with BotFather (token N) and adds it to the
|
|
57
|
-
channel as an administrator that may post and delete messages (door). In the
|
|
58
|
-
local storage) she sets TELEGRAM_TOKEN to token N, and then chooses to add Telegram;
|
|
59
|
-
shows the command to post, "/connect" and a word, and she posts it in the channel (door).
|
|
57
|
+
channel as an administrator that may post and delete messages (door). In the Scheduler she runs herself (docker compose,
|
|
58
|
+
local storage) she sets TELEGRAM_TOKEN to token N, and then chooses to add Telegram; Scheduler
|
|
59
|
+
shows the command to post, "/connect" and a word, and she posts it in the channel (door). Scheduler's connect screen
|
|
60
60
|
polls (getUpdates, its library sending allowed_updates as the fields allowed_updates[0]=message and
|
|
61
61
|
allowed_updates[1]=channel_post, which the Bot API does not read as its JSON-serialized list, so every update type
|
|
62
|
-
comes back): the bot's own membership change and her post come back.
|
|
62
|
+
comes back): the bot's own membership change and her post come back. Scheduler reads its bot (getMe), checks the bot
|
|
63
63
|
may delete messages there (getChatMember: an administrator with can_delete_messages), deletes her /connect post
|
|
64
64
|
(deleteMessage), posts "Connection Successful. Message will be deleted in 10 seconds." (sendMessage) and, ten
|
|
65
65
|
seconds later, deletes that too (deleteMessage). It then reads the channel (getChat), the photo's file (getFile), and copies the photo into its
|
|
66
66
|
storage from the file's link (the file download).
|
|
67
|
-
6. **Thursday 8 January, 10:00. The launch post, and the release notes.**
|
|
67
|
+
6. **Thursday 8 January, 10:00. The launch post, and the release notes.** Scheduler publishes Ana's announcement, bold title and two paragraphs
|
|
68
68
|
(sendMessage, parse_mode HTML).
|
|
69
69
|
At 11:00 Ana asks the agent in her private chat for the 0.9 release notes by Friday; Harness's poll receives it,
|
|
70
70
|
it shows the bot typing, and the agent answers that the work is card t_7c1e9a04 on its board and that this chat
|
|
@@ -72,23 +72,23 @@ is a member; a bot deletes another's message in a channel only with the right to
|
|
|
72
72
|
January, 15:00**: the card is done with its notes file, and Harness's board tells the chat: the notice "card … done
|
|
73
73
|
— Draft the 0.9 release notes" and its summary as the caption of the file (sendDocument, the file uploaded, the
|
|
74
74
|
caption in MarkdownV2 as the Chat SDK escapes it).
|
|
75
|
-
7. **Monday 12 January, 10:00. A release with screenshots.**
|
|
75
|
+
7. **Monday 12 January, 10:00. A release with screenshots.** Scheduler publishes the release post with three screenshots
|
|
76
76
|
as one album, the text on the first (sendMediaGroup, the images uploaded). At 11:00 it publishes the post's comment,
|
|
77
|
-
the changelog, as a reply to the album's first message (sendMessage with
|
|
77
|
+
the changelog, as a reply to the album's first message (sendMessage with reply_parameters naming it).
|
|
78
78
|
8. **Monday 12 January, 18:00. The standups move.** The team moves its standups to a video call and Ana removes the
|
|
79
79
|
agent bot from "Tide Labs team" (door), but leaves the digest job on. Tuesday 13 January at 09:15 the job posts its
|
|
80
80
|
digest to the home chat, which says no standup items were posted this week (that morning's standup was on the
|
|
81
81
|
call), and Telegram refuses: "Forbidden: bot was kicked from the group chat". Ana deletes the job in Harness (no
|
|
82
82
|
Telegram call).
|
|
83
83
|
9. **Wednesday 14 January, 16:00. A caption too long.** Ana's next post is one product photo with a 1,091-character
|
|
84
|
-
story.
|
|
85
|
-
("Bad Request: message caption is too long");
|
|
86
|
-
to a paragraph and
|
|
87
|
-
10. **Monday 19 January, 11:00. A demo and a paper.**
|
|
84
|
+
story. Scheduler sends it (sendPhoto) and Telegram refuses it: a photo's caption holds at most 1,024 characters
|
|
85
|
+
("Bad Request: message caption is too long"); Scheduler shows "Telegram rejected the post". At 16:20 she cuts the story
|
|
86
|
+
to a paragraph and Scheduler sends it again, which posts.
|
|
87
|
+
10. **Monday 19 January, 11:00. A demo and a paper.** Scheduler publishes the product demo video (sendVideo, uploaded) and,
|
|
88
88
|
at 15:00, the white paper as a PDF (sendDocument, uploaded).
|
|
89
89
|
11. **Friday 27 February, 17:00. The agent retired.** Ana stops using the agent on Telegram and, in BotFather, makes a new
|
|
90
90
|
token for it (/token), which revokes token A. Harness, still running on her laptop, polls with it and is refused ("Unauthorized"); she stops it. The
|
|
91
|
-
news channel, its posts and the news bot stay with
|
|
91
|
+
news channel, its posts and the news bot stay with Scheduler.
|
|
92
92
|
|
|
93
93
|
## What the story reaches
|
|
94
94
|
|
|
@@ -96,4 +96,4 @@ getMe (both bots), deleteWebhook, getUpdates (held, a long poll; with allowed_up
|
|
|
96
96
|
privacy mode (a plain member bot sent a service message and not a plain mention; an administrator bot sent every
|
|
97
97
|
message), sendChatAction, sendMessage (plain, HTML, a reply; refused for a removed bot), getChatMember, deleteMessage
|
|
98
98
|
(twice), getChat, getFile, the file download, sendPhoto (refused for its caption, then sent), sendVideo, sendDocument
|
|
99
|
-
(
|
|
99
|
+
(Scheduler's PDF; Harness's notes with a MarkdownV2 caption), sendMediaGroup; and a revoked token's refusal.
|
|
@@ -1,75 +1,40 @@
|
|
|
1
1
|
{
|
|
2
2
|
"judge": {
|
|
3
|
-
"agent": "Claude
|
|
4
|
-
"name": "
|
|
3
|
+
"agent": "Claude journey judge (Opus)",
|
|
4
|
+
"name": "Independent journey judge"
|
|
5
5
|
},
|
|
6
6
|
"authors": [
|
|
7
|
-
"
|
|
7
|
+
"yueranyuan",
|
|
8
|
+
"Aaron (A-001)",
|
|
9
|
+
"Claude Opus 5.5",
|
|
10
|
+
"Codex"
|
|
8
11
|
],
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"judgedAt": "2026-10-02",
|
|
12
|
+
"sha256": "4186f9087ab35bb7639a6d5aaa3471c51695ed2be4c086e417a7e2ebd2310d19",
|
|
13
|
+
"judgedAt": "2026-10-15",
|
|
12
14
|
"plausible": true,
|
|
13
15
|
"rulings": [
|
|
14
16
|
{
|
|
15
|
-
"id": "
|
|
17
|
+
"id": "reply-to-message-id-era",
|
|
16
18
|
"steps": [
|
|
17
|
-
"act
|
|
18
|
-
"act 4",
|
|
19
|
-
"act 7",
|
|
20
|
-
"act 8",
|
|
21
|
-
"act 9",
|
|
22
|
-
"act 10"
|
|
19
|
+
"act 7"
|
|
23
20
|
],
|
|
24
|
-
"barItem": "
|
|
25
|
-
"reason": "Act
|
|
26
|
-
"correction": "
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
"id": "postiz-never-given-token-n",
|
|
30
|
-
"steps": [
|
|
31
|
-
"Who acts",
|
|
32
|
-
"act 5"
|
|
33
|
-
],
|
|
34
|
-
"barItem": "the wrong actor or credential for an act",
|
|
35
|
-
"reason": "Postiz posts to Telegram through the one bot its deployment configures, process.env.TELEGRAM_TOKEN (postiz-app e0a08a7, libraries/nestjs-libraries/src/integrations/social/telegram.provider.ts:19). In hosted Postiz, that bot is Postiz's own. The outline calls @tidelabs_news_bot, token N, \"Postiz's Telegram integration\", and in act 5 Ana makes the bot and Postiz then calls with it. The outline never says that she runs Postiz herself or that token N becomes its TELEGRAM_TOKEN.",
|
|
36
|
-
"correction": "In 'Who acts' and act 5, say that Ana self-hosts Postiz (docker compose, local storage) and sets its TELEGRAM_TOKEN to token N before she adds Telegram."
|
|
21
|
+
"barItem": "the wrong era: building on an API the vendor had deprecated by the World's date; a call through a door the vendor does not document",
|
|
22
|
+
"reason": "Act 7 has Scheduler publish the changelog comment as a reply 'with reply_to_message_id'. Telegram replaced that parameter in Bot API 7.0, December 29, 2023 (https://core.telegram.org/bots/api-changelog: 'Replaced parameters reply_to_message_id and allow_sending_without_reply in the methods ... with the field reply_parameters'), two years before the story's January 2026, and the reference page the spec is written from (https://core.telegram.org/bots/api#sendmessage, Bot API 10.3) no longer documents it at all, as spec/SOURCE.md itself states; the act builds on a door the vendor withdrew, even though the server still reads it.",
|
|
23
|
+
"correction": "Act 7 sends the reply with reply_parameters (a JSON-serialized ReplyParameters naming the album's first message_id), as https://core.telegram.org/bots/api#sendmessage documents, and the 'What the story reaches' line says so."
|
|
37
24
|
}
|
|
38
25
|
],
|
|
39
26
|
"applied": {
|
|
40
|
-
"from": "
|
|
27
|
+
"from": "4bdc79fa09692fb332a4eac8080c9a10e5d7b2234435712284ef4e599d37d4eb",
|
|
41
28
|
"wasPlausible": false,
|
|
42
29
|
"steps": [
|
|
43
|
-
"
|
|
44
|
-
"5",
|
|
45
|
-
"8",
|
|
46
|
-
"9",
|
|
47
|
-
"10"
|
|
30
|
+
"act 7"
|
|
48
31
|
],
|
|
49
32
|
"rulings": [
|
|
50
33
|
{
|
|
51
|
-
"id": "three-tuesdays-skipped",
|
|
52
|
-
"steps": [
|
|
53
|
-
"act 3",
|
|
54
|
-
"act 4",
|
|
55
|
-
"act 7",
|
|
56
|
-
"act 8",
|
|
57
|
-
"act 9",
|
|
58
|
-
"act 10"
|
|
59
|
-
],
|
|
60
|
-
"barItem": "a stated cause that never happens, and a promise never kept",
|
|
61
|
-
"reason": "Act 3 sets the standup weekly on Tuesdays and makes the agent an administrator, which is sent every group message (https://core.telegram.org/bots/features#privacy-mode). Act 4 runs the first standup and digest on 6 January. The standups move to the call only on Monday 2 February (act 10). Tuesdays 13, 20 and 27 January fall within acts 7-9 with no standup, no poll and no digest. Act 10's digest then says that no items were posted \"this week\", as if earlier weeks had them.",
|
|
62
|
-
"correction": "Move act 10 to Monday 12 January, 18:00, so that the refused digest is Tuesday 13 January's. Or tell the three January Tuesdays' standups and digests."
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
"id": "postiz-never-given-token-n",
|
|
66
34
|
"steps": [
|
|
67
|
-
"
|
|
68
|
-
"act 5"
|
|
35
|
+
"act 7"
|
|
69
36
|
],
|
|
70
|
-
"
|
|
71
|
-
"reason": "Postiz posts to Telegram through the one bot its deployment configures, process.env.TELEGRAM_TOKEN (postiz-app e0a08a7, libraries/nestjs-libraries/src/integrations/social/telegram.provider.ts:19). In hosted Postiz, that bot is Postiz's own. The outline calls @tidelabs_news_bot, token N, \"Postiz's Telegram integration\", and in act 5 Ana makes the bot and Postiz then calls with it. The outline never says that she runs Postiz herself or that token N becomes its TELEGRAM_TOKEN.",
|
|
72
|
-
"correction": "In 'Who acts' and act 5, say that Ana self-hosts Postiz (docker compose, local storage) and sets its TELEGRAM_TOKEN to token N before she adds Telegram."
|
|
37
|
+
"why": "Act 7 sends the reply with reply_parameters (a JSON-serialized ReplyParameters naming the album's first message_id), as https://core.telegram.org/bots/api#sendmessage documents, and the 'What the story reaches' line says so."
|
|
73
38
|
}
|
|
74
39
|
]
|
|
75
40
|
}
|
|
@@ -1,133 +1,59 @@
|
|
|
1
1
|
{
|
|
2
2
|
"judge": {
|
|
3
|
-
"agent": "Claude
|
|
4
|
-
"name": "
|
|
3
|
+
"agent": "Claude journey judge (Opus)",
|
|
4
|
+
"name": "Independent journey judge"
|
|
5
5
|
},
|
|
6
6
|
"authors": [
|
|
7
|
-
"
|
|
7
|
+
"yueranyuan",
|
|
8
|
+
"Aaron (A-001)",
|
|
9
|
+
"Claude Opus 5.5",
|
|
10
|
+
"Codex"
|
|
8
11
|
],
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"judgedAt": "2026-10-02",
|
|
12
|
+
"sha256": "d4f45ec531a3cafd7ec746629b2fb110cf5bb5adb0664f52a5d279eaf7f59ad3",
|
|
13
|
+
"judgedAt": "2026-10-15",
|
|
12
14
|
"plausible": true,
|
|
13
15
|
"rulings": [
|
|
14
16
|
{
|
|
15
|
-
"id": "
|
|
17
|
+
"id": "reply-to-message-id-era",
|
|
16
18
|
"steps": [
|
|
17
|
-
|
|
18
|
-
20,
|
|
19
|
-
22,
|
|
20
|
-
30,
|
|
21
|
-
58,
|
|
22
|
-
62,
|
|
23
|
-
66,
|
|
24
|
-
70,
|
|
25
|
-
73
|
|
19
|
+
61
|
|
26
20
|
],
|
|
27
|
-
"barItem": "
|
|
28
|
-
"reason": "
|
|
29
|
-
"correction": "
|
|
21
|
+
"barItem": "the wrong era: building on an API the vendor had deprecated by the World's date; a call through a door the vendor does not document",
|
|
22
|
+
"reason": "Step 61 (Monday 12 January 2026) replies to the album with the form field reply_to_message_id={album}. Telegram replaced that parameter in Bot API 7.0, December 29, 2023 (https://core.telegram.org/bots/api-changelog: 'Replaced parameters reply_to_message_id and allow_sending_without_reply in the methods ... with the field reply_parameters'), and the page the spec is written from (https://core.telegram.org/bots/api#sendmessage, Bot API 10.3) no longer documents it; spec/SOURCE.md admits the page 'no longer lists it' and patches it in. A step through a parameter the vendor withdrew two years before the World's date is rejected even where the twin answers it.",
|
|
23
|
+
"correction": "Step 61 sends reply_parameters={\"message_id\":{album}} (JSON-serialized ReplyParameters, as https://core.telegram.org/bots/api#sendmessage documents) in place of reply_to_message_id, keeping its expectation result.reply_to_message.message_id equals {album}."
|
|
30
24
|
},
|
|
31
25
|
{
|
|
32
|
-
"id": "
|
|
26
|
+
"id": "photo-sizes-order",
|
|
33
27
|
"steps": [
|
|
34
|
-
33,
|
|
35
|
-
37,
|
|
36
|
-
40,
|
|
37
|
-
41,
|
|
38
|
-
42,
|
|
39
|
-
43,
|
|
40
|
-
45,
|
|
41
|
-
46,
|
|
42
|
-
47,
|
|
43
|
-
48,
|
|
44
|
-
50,
|
|
45
28
|
59,
|
|
46
|
-
61,
|
|
47
|
-
63,
|
|
48
|
-
65,
|
|
49
|
-
67,
|
|
50
29
|
69
|
|
51
30
|
],
|
|
52
|
-
"barItem": "
|
|
53
|
-
"reason": "
|
|
54
|
-
"correction": "
|
|
55
|
-
},
|
|
56
|
-
{
|
|
57
|
-
"id": "running-harness-polls-without-offset",
|
|
58
|
-
"steps": [
|
|
59
|
-
76
|
|
60
|
-
],
|
|
61
|
-
"barItem": "content that does not bear out the step's name",
|
|
62
|
-
"reason": "Step 76 is Harness \"still running on her laptop\". The adapter it runs keeps its offset in its polling loop and sends it on every poll: `offset = update.update_id + 1` (@chat-adapter/telegram 4.39.0, dist/index.js:3327-3345, pollingLoop; demand.json: \"confirming the last with offset\"). The life last confirmed one at step 53. Step 76's body, {\"limit\": 100, \"timeout\": 30}, is the request a freshly started adapter sends (step 9), not the request of the process the step names.",
|
|
63
|
-
"correction": "Step 76's body: {\"offset\": \"{agent_next}\", \"limit\": 100, \"timeout\": 30}."
|
|
31
|
+
"barItem": "vendor behaviour the vendor's documentation contradicts",
|
|
32
|
+
"reason": "Step 59 expects result.0.photo.0.width 480 and result.2.photo.0.height 300 for 480x300 PNG uploads, and step 69 expects result.photo.0.width 640 and height 480 for a 640x480 JPEG: the first PhotoSize being the uploaded image itself. Telegram 'attaches a vector of thumbnails with reduced resolution to all uploaded media', the smallest type s 'bounded by 100x100 pixels' and m by 320x320 (https://core.telegram.org/api/files, image thumbnail types; Message.photo is 'available sizes of the photo', https://core.telegram.org/bots/api#message), and the Bot API answers them in ascending order (TDLib at 42e6a52, td/telegram/PhotoSize.cpp get_photo_sizes_object, stable_sort by size then width*height, the TDLib source the spec cites). photo.0 is the 100-pixel thumbnail; the original's dimensions are on the last size.",
|
|
33
|
+
"correction": "Steps 59 and 69 expect the uploaded dimensions on the last PhotoSize (step 59: result.0.photo.2.width 480 and result.2.photo.2.height 300; step 69: result.photo.2.width 640 and height 480), with photo.0 the s thumbnail, bounded by 100x100."
|
|
64
34
|
}
|
|
65
35
|
],
|
|
66
36
|
"applied": {
|
|
67
|
-
"from": "
|
|
37
|
+
"from": "8251bda4592d9f3dae1bb5067727bee657d212ebd5aca36c32e8a7f4d1beb222",
|
|
68
38
|
"wasPlausible": false,
|
|
69
39
|
"steps": [
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
"
|
|
73
|
-
"70",
|
|
74
|
-
"71",
|
|
75
|
-
"72",
|
|
76
|
-
"73",
|
|
77
|
-
"74",
|
|
78
|
-
"76"
|
|
40
|
+
"59",
|
|
41
|
+
"61",
|
|
42
|
+
"69"
|
|
79
43
|
],
|
|
80
44
|
"rulings": [
|
|
81
45
|
{
|
|
82
|
-
"id": "three-tuesdays-skipped",
|
|
83
46
|
"steps": [
|
|
84
|
-
|
|
85
|
-
20,
|
|
86
|
-
22,
|
|
87
|
-
30,
|
|
88
|
-
58,
|
|
89
|
-
62,
|
|
90
|
-
66,
|
|
91
|
-
70,
|
|
92
|
-
73
|
|
47
|
+
61
|
|
93
48
|
],
|
|
94
|
-
"
|
|
95
|
-
"reason": "Steps 16, 20 and 22 set the standup for 9:00 every Tuesday, with items posted in the group, and the agent promises the digest at 9:15. From step 19 the agent is an administrator, and an administrator is sent every group message (https://core.telegram.org/bots/features#privacy-mode, \"bot admins always receive all messages\"). The job runs once, Tuesday 6 January (step 30). The team keeps the group standup until Monday 2 February (step 70: \"the standups move to a video call\"), yet Tuesdays 13, 20 and 27 January pass inside steps 58-70 with no items posted, no poll and no digest. Step 73's digest then says \"No standup items were posted this week\", which implies the earlier weeks had items. Three of the four weekly runs the story promises never happen, and nothing in the story explains why.",
|
|
96
|
-
"correction": "Move the standups' move and the bot's removal to Monday 12 January, 18:00, after step 61. The job's next run, Tuesday 13 January at 09:15, is then the refused one, and the waits to Wednesday 14 January 16:00 and onward are adjusted. Alternatively, show the Tuesday standups of 13, 20 and 27 January: items posted, a poll, and a digest each week."
|
|
49
|
+
"why": "Step 61 sends reply_parameters={\"message_id\":{album}} (JSON-serialized ReplyParameters, as https://core.telegram.org/bots/api#sendmessage documents) in place of reply_to_message_id, keeping its expectation result.reply_to_message.message_id equals {album}."
|
|
97
50
|
},
|
|
98
51
|
{
|
|
99
|
-
"id": "postiz-never-given-token-n",
|
|
100
52
|
"steps": [
|
|
101
|
-
33,
|
|
102
|
-
37,
|
|
103
|
-
40,
|
|
104
|
-
41,
|
|
105
|
-
42,
|
|
106
|
-
43,
|
|
107
|
-
45,
|
|
108
|
-
46,
|
|
109
|
-
47,
|
|
110
|
-
48,
|
|
111
|
-
50,
|
|
112
53
|
59,
|
|
113
|
-
61,
|
|
114
|
-
63,
|
|
115
|
-
65,
|
|
116
|
-
67,
|
|
117
54
|
69
|
|
118
55
|
],
|
|
119
|
-
"
|
|
120
|
-
"reason": "Postiz's Telegram provider calls with one bot, the one its deployment configures: `new TelegramBot(process.env.TELEGRAM_TOKEN!)` (libraries/nestjs-libraries/src/integrations/social/telegram.provider.ts:19, postiz-app e0a08a7; demand.json, Postiz's client: \"TELEGRAM_TOKEN\"). In hosted Postiz, that is Postiz's own bot and not one a customer makes. Step 33 has Ana make @tidelabs_news_bot \"for Postiz\", and from step 37 on Postiz calls with {news_token}. But no step or name says that Ana runs Postiz herself, or that token N is set as its TELEGRAM_TOKEN. The life never shows how the credential Postiz uses reaches it, and as written it reads as the hosted product calling with a bot that belongs to the customer.",
|
|
121
|
-
"correction": "In step 33 or a step beside it, say that Ana runs Postiz herself (docker compose, local storage, as demand.json reads it) and sets TELEGRAM_TOKEN to the news bot's token before she adds Telegram. Use the same wording in the outline."
|
|
122
|
-
},
|
|
123
|
-
{
|
|
124
|
-
"id": "running-harness-polls-without-offset",
|
|
125
|
-
"steps": [
|
|
126
|
-
76
|
|
127
|
-
],
|
|
128
|
-
"barItem": "content that does not bear out the step's name",
|
|
129
|
-
"reason": "Step 76 is Harness \"still running on her laptop\". The adapter it runs keeps its offset in its polling loop and sends it on every poll: `offset = update.update_id + 1` (@chat-adapter/telegram 4.39.0, dist/index.js:3327-3345, pollingLoop; demand.json: \"confirming the last with offset\"). The life last confirmed one at step 53. Step 76's body, {\"limit\": 100, \"timeout\": 30}, is the request a freshly started adapter sends (step 9), not the request of the process the step names.",
|
|
130
|
-
"correction": "Step 76's body: {\"offset\": \"{agent_next}\", \"limit\": 100, \"timeout\": 30}."
|
|
56
|
+
"why": "Steps 59 and 69 expect the uploaded dimensions on the last PhotoSize (step 59: result.0.photo.2.width 480 and result.2.photo.2.height 300; step 69: result.photo.2.width 640 and height 480), with photo.0 the s thumbnail, bounded by 100x100."
|
|
131
57
|
}
|
|
132
58
|
]
|
|
133
59
|
}
|