-
Notifications
You must be signed in to change notification settings - Fork 6
/
chapter5.html
1497 lines (1222 loc) · 167 KB
/
chapter5.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta charset="utf-8" />
<title>Standards for the Social Web</title>
<meta content="width=device-width, initial-scale=1" name="viewport" />
<link href="thesis.css" media="all" rel="stylesheet" title="Thesis do" />
<link href="https://dokie.li/media/css/basic.css" media="all" rel="stylesheet alternate" title="Basic" />
<link href="https://dokie.li/media/css/dokieli.css" media="all" rel="stylesheet" />
<script src="https://dokie.li/scripts/dokieli.js"></script>
<script src="thesis.js"></script>
<!-- <link href="https://rhiaro.co.uk/incoming/" rel="http://www.w3.org/ns/ldp#inbox" /> -->
<!-- <link href="https://linkedresearch.org/annotation/rhiaro/thesis/" rel="http://www.w3.org/ns/oa#annotationService" /> -->
<style>
h1:before {
content:"Chapter 5\A" !important;
white-space:pre;
font-size:0.75em;
}
</style>
</head>
<body about="" prefix="rdf: http://www.w3.org/1999/02/22-rdf-syntax-ns# rdfs: http://www.w3.org/2000/01/rdf-schema# owl: http://www.w3.org/2002/07/owl# xsd: http://www.w3.org/2001/XMLSchema# dcterms: http://purl.org/dc/terms/ dctypes: http://purl.org/dc/dcmitype/ foaf: http://xmlns.com/foaf/0.1/ pimspace: http://www.w3.org/ns/pim/space# cc: https://creativecommons.org/ns# skos: http://www.w3.org/2004/02/skos/core# prov: http://www.w3.org/ns/prov# mem: http://mementoweb.org/ns# qb: http://purl.org/linked-data/cube# schema: http://schema.org/ void: http://rdfs.org/ns/void# rsa: http://www.w3.org/ns/auth/rsa# cert: http://www.w3.org/ns/auth/cert# wgs: http://www.w3.org/2003/01/geo/wgs84_pos# bibo: http://purl.org/ontology/bibo/ sioc: http://rdfs.org/sioc/ns# doap: http://usefulinc.com/ns/doap# dbr: http://dbpedia.org/resource/ dbp: http://dbpedia.org/property/ sio: http://semanticscience.org/resource/ opmw: http://www.opmw.org/ontology/ deo: http://purl.org/spar/deo/ doco: http://purl.org/spar/doco/ cito: http://purl.org/spar/cito/ fabio: http://purl.org/spar/fabio/ oa: http://www.w3.org/ns/oa# as: https://www.w3.org/ns/activitystreams# ldp: http://www.w3.org/ns/ldp# solid: http://www.w3.org/ns/solid/terms# acl: http://www.w3.org/ns/auth/acl# dio: https://w3id.org/dio# rel: https://www.w3.org/ns/iana/link-relations/relation#" typeof="schema:CreativeWork sioc:Post prov:Entity">
<main>
<article about="" typeof="schema:Article">
<h1 property="schema:name">Standards for the Social Web</h1>
<div id="content">
<section id="introduction" rel="schema:hasPart">
<h2>Introduction</h2>
<div>
<p>Many of the systems discussed in the previous chapter have proven foundational for ongoing efforts to create standards for decentralised social interactions on the Web. <a href="chapter4#socialwg">Previously</a> we gave an overview of the standards being produced by the W3C Social Web Working Group; now we discuss in more depth notable decisions and debates of the group, describe the resulting standards in more detail, and outline how to actually go about building decentralised social systems which empower self-presentation using these standards. The contributions of this chapter are as follows:</p>
<ul>
<li>A critical analysis of contemporary standards for decentralised social interaction on the Web, taking into account social dynamics of collaborative projects and the W3C consensus model, as well as the technical considerations.</li>
<li>A characterisation of the problems being solved by the Social Web WG, and how these relate to the more specific problem of online self-presentation, by means of the conceptual framework from chapter 3.</li>
<li>A technical primer for the work produced by the group (published by the W3C as a Working Group Note: <em>Social Web Protocols</em>).</li>
<li>Prototype implementations of standards produced by the group, and a report on their interoperability with implementations produced by others.</li>
</ul>
<p>This chapter brings together the qualitative research from earlier with concrete technical outcomes in the form of protocol designs. The work of the Social Web Working Group is in effect a case study for designing decentralised Social Web systems, but what is presented here is more than a survey or observational study. Since I was first a member of the Working Group, and then the W3C Team Contact, I was immersed in every part of the decision making and contributed in some form to all of the specifications produced. The <em>Social Web Protocols</em> document contributes a deeper understanding of the various protocols, and importantly how they can complement or contradict each other. This document is particularly useful <em>because</em> of the complicated social dynamics of the group, and produced as an introductory piece for developers entering this space anew. Technical decisions that have been made by the Working Group over the past (almost) three years were not made in a vacuum, nor dictated by cold logic, but rarely backed up with truly meaningful data. Most decisions were made on the - admittedly well-honed - gut instinct of experts, data from small samples, and anecdotal evidence. The specifications that resulted were influenced by this, so it is important to examine the development processes. <em>Social Web Protocols</em> contains fine technical details of the Working Group's recommendations, which are important for a complete picture and analysis of the current cutting-edge of decentralised Social Web standards. An overview of Social Web Protocols is presented in this section, and the specifics can be found in <a href="#">Appendix SWP</a>.</p>
<!-- <ul class="note">
<li>Summary of current SocialWG activities.</li>
<li>Deriving things from user stories - https://rhiaro.co.uk/2015/08/api-requirements</li>
<li>Various other key decision / pivot points, and analysis</li>
<li>How do SWWG specs relate to CCCCC framework</li>
<li>Implementations</li>
</ul>
-->
</div>
</section>
<section id="socialwg-thesis" rel="schema:hasPart">
<h2>Standards and self-presentation</h2>
<div>
<p>We have in previous chapters established that online self-presentation is greatly more complex than listing attributes and a photo on a Web page. For decentralised systems to emulate the multitude of self-presentation possibilities provided by mainstream centralised systems today they must coordinate across a range of potential user activities and interactions. Common protocols enable disparate systems to communicate without any prior arrangements. Specifications describing such protocols must be agreed upon and published in such a way that makes them easy to find, and appear authoritative enough that developers of decentralised systems are persuaded to implement them.</p>
<p>This section documents and furthers the standardisation process, as part of the work of the W3C Social Web Working Group. <a href="chapter4#socialwg">Chapter 4</a> includes a survey of the specifications and their implementations at the time of writing; here I provide a behind-the-scenes look at and contribution to their development.</p>
<section id="swwg-context" rel="schema:hasPart">
<h3>Standardisation as Context</h3>
<div>
<blockquote><p>The benefits and costs of standardisation are a prominent socio-technical factor [<a href="appendices#ref-crit12">crit12</a>]</p></blockquote>
<p>The standards developed by the Social Web Working Group will be used as the basis for systems which incorporate social features, and as such, create the opportunity for users of the system to present some aspects of their personhood in an online space. This chapter goes into detail about the non-technical parts of development of these standards.</p>
<p>The reason for this is as follows: the formation of the Working Group and its charter design; the individual members of the Group and their particular interests and experiences; and the processes of the W3C, all serve to make up part of the <strong>context</strong> (one of the 5 Cs from <a href="chapter3#ccccc">Chapter 3</a>) of any systems built from these standards. This is an example of things to analyse, or at least take note of, with respect to the industrial or organisational context in which users of social systems are engaging in self-presentation.</p>
</div>
</section>
<section id="swwg-process" rel="schema:hasPart">
<h3>The standardisation process</h3>
<div>
<p>Once a group is formed and participants are in place, the W3C has many processes in place to facilitate standards development. These processes have ramifications on the end result of worked produced by Working Groups, so I will outline key processes here. </p>
<p>Specifications advance usually over the course of one to two years, through a number of stages of increasing stability, to bring them to a final status of <em>REC</em> (recommendation). Each stage (see also [<a href="appendices#ref-w3c-maturity">w3c-maturity</a>]) is designed to elicit development, input, and review from different qualified parties to iron out bugs, correct omissions, and generally make sure the specification will do what it is intended to do. While direct input is limited to Working Group members, specification development is carried out in public. Each date-stamped draft is online for anyone to review, mailing list archives, meeting minutes, wiki pages, and (at least in the case of the Social Web Working Group) IRC logs are publicly visible. Working Groups tend to take public comments over a specific mailing list, or as GitHub issues, and are obliged to be responsive and reach a considered resolution on how to handle all feedback so that commenters feel heard.</p>
<p>Specifications are maintained as Editor's Drafts (ED) throughout their life cycle. An ED is the most up to date version of the specification, and updated at the editor's discretion. Working Groups do not have the authority to publish specifications unsupervised. Each Working Group is supported by one or two W3C employees (Team Contacts), and at each transition from one specification maturity level to the next, a request is sent to the W3C Director, who reviews the relevant information, checks that the Working Group have been handling feedback from commenters appropriately, clarifies any points of confusion, and grants or denies the request.</p>
<p>The first formal iteration (hosted at the W3C domain) is the First Public Working Draft (FPWD). An ED need not be perfect, or even complete, but when it is sufficiently outlined the Working Group participants vote to publish the FPWD. This is the first stage of the Working Group committing to progress the document towards recommendation. As the specification is discussed and implemented, and feedback comes in, features are added, removed and refined. After each batch of major changes to the ED, the Working Group may vote to publish updated Working Drafts (WD). WDs are essentially official snapshots at particular points in time. As a specification becomes stable (ie. it receives fewer and fewer major changes) the Working Group reaches out further to solicit 'wide review' from relevant communities. These may be outside the W3C as necessary, but there are specific groups inside the W3C who are expected to review all specifications along particular dimensions; namely: security and privacy, internationalisation, and accessibility.</p>
<p>When the specification is sufficiently stable, and wide review has been achieved, the Working Group may vote to advance to Candidate Recommendation (CR). The CR phase lasts for a minimum of four weeks. This commences a broader call for implementations from outside of the W3C, begins the window in which W3C members must disclose patent conflicts, and prompts W3C Advisory Committee members to review the specification. If major (non-editorial) changes are made to the specification during this phase (which is not uncommon as a result of third-party implementation feedback), then a new CR must be published, which restarts the four week time period. During this time, the editors and their collaborators should be polishing up official test suites, and soliciting implementation reports. The specification can advance to Proposed Recommendation (PR) when it meets a CR exit criteria previously defined by Working Group consensus. In the case of the Social Web Working Group, specifications are expected to have tests and reports for at least two independent implementations of each feature of a specification (where 'feature' is defined per specification). During PR, which must also last a minimum of four weeks, Advisory Committee representatives are re-prompted to review the spec. This is the last time during which anyone can make a Formal Objection to the specification's progression, or raise patent conflicts. <em>Finally</em>, if enough positive Advisory Committee reviews are received, the W3C Director approves the specification to transition to REC. It is carved in stone.</p>
<p>Why am I telling you all this?</p>
<p>This is an example of organisational processes having impact on technology design long before the technology is in the hands of end users. The specifications of the Social Web Working Group were not only moulded by their editors and Working Group participants, but reshaped and influenced by W3C staff and by representatives of paying W3C Members who weren't participating in the Group directly. Specifications were poked and tweaked by other Working Groups who do not specialise in the Social Web (most contentious input came from the Internationalisation (i18n) Working Group), as well as critiqued by complete outsiders at every step of the way.</p>
<p>Most specification editors in the Social Web Working Group were invited experts, and thus not paid by an organisation for their contributions. They were working on these specifications, attending weekly telecons, and often quarterly face-to-face meetings, on their own time, and own dime. Editors are also burdened with test suite development; no small task. The W3C process imposes structure, deadlines and deliverables to the specification development process that may be missing (or certainly different) were the specs advanced elsewhere. These deadlines and review processes ultimately affect what is included in a specification, and what is removed. Smaller specs are easier to review, easier to test, and therefore faster to progress. This tended to mean that when in doubt, features were dropped or marked as 'at risk' rather than have them hold up progress. In particular, ActivityStreams 2.0 was brutally trimmed down over the years, and requests for additions to the vocabulary were automatically rejected after a certain point for fear of slowing things down. I wonder how these exclusions will impact future software designed around AS2.</p>
<p>Something else worth bearing in mind is that for all of this <em>process</em>, it is commonly held that most 'regular Web developers' don't know about or don't care about (or both) the difference between the different maturity levels of W3C specifications, or even the difference between a Recommendation and a Note. This makes it fairly easy for developers to be implementing software on the basis of an out of date document, or giving weight to a protocol design that was ultimately rejected or even unfinished. Not everything with the W3C stamp on has been fully thought through or passed quality tests, but not every developer realises this.</p>
</div>
</section>
<section id="swwg-charter" rel="schema:hasPart">
<h3>The Social Web Working Group charter</h3>
<div>
<!-- <p class="todo">Maybe move some of this back to the last section in C4 after all</p> -->
<p>Technical specifications, at least those produced by the W3C, are intended for software developers. A mark of the success of a standard is when multiple developers, who have no knowledge of each others' activities, can independently implement the specification into code and have their systems interoperate successfully.</p>
<blockquote><p>Interoperability: ability of a system ... to work with or use the parts or equipment of another system - <em>Merriam Webster Dictionary</em></p></blockquote>
<p>Contributions to W3C standards may be made by individuals representing themselves (if invited and approved by Working Group chairs), but more so by representatives of organisations which pay for membership to the W3C. As the Web is an open platform on which anyone can build, there is a lot of space for many ways to solve the same problems. This is a virtue in that it promotes innovation and competition amongst Web services, but a problem if it results in technical fragmentation of solutions, whereby end users are forced to choose one and forgo (or uncomfortably juggle) interaction with others (remember the 'browser wars' of the 1990s and early 2000s? [<a href="appendices#ref-bwars">bwars</a>]). Organisations join the W3C so that their interests may be represented as they collaborate to produce standard ways of interacting with Web technologies in order to reduce the negative impact of technical fragmentation on end users. </p>
<p>As has been raised on multiple occasions by this thesis, the Social Web is presently in a state of technical fragmentation [<a href="appendices#ref-dcent">dcent</a>]. End users, also known as people or human beings, are living with the effects of this on a daily basis. Beyond being a mere inconvenience (not being able to port one's friends from Twitter to Facebook), the competition between social platforms has developed in such a way that people are <em>locked in</em> to services. Once one depends upon a particular social networking platform for communication and content creation it is almost impossible to change provider. Platforms like this have come to be known amongst decentralisation advocates as <em>silos</em>, in that they do not let information flow in or out [<a href="appendices#ref-timblfuture">timblfuture</a>].</p>
<blockquote><p>Silo: a trench ... usually sealed to exclude air and used for making and storing silage - <em>Merriam Webster Dictionary</em></p></blockquote>
<p>These closed systems bring a plethora of social, cultural, political and economic issues, which have been touched upon at various stages elsewhere in this thesis and we will not detail further here. The <em>Social Activity</em><sup><a href="#fn-act">act</a></sup>, which includes the Social Web Working Group, was created in W3C with an eye to promoting interoperability between social systems, and breaking down some of the walls of silos.</p>
<blockquote><p>The focus of the Social Activity is on making "social" a first-class citizen of the Open Web Platform by enabling standardized protocols, APIs, and an architecture for standardized communication among Social Web applications. - <a href="https://www.w3.org/Social/">W3C Social Activity</a></p></blockquote>
<p>Objectives of the Social Web Working Group were to produce standards for:</p>
<ul>
<li>a syntax and vocabulary for describing social data;</li>
<li>an API for reading and writing social data (create, read, update, delete);</li>
<li>a federation API for passing social data between disparate systems (subscriptions and notifications).</li>
</ul>
<aside class="note">
<p id="fn-act"><sup>act</sup> a W3C 'Activity' is a framework for clustering related Working Groups and Interest Groups together.</p>
</aside>
</div>
</section>
<section id="swwg-participants-and-audience" rel="schema:hasPart">
<h3>Working Group participants and audience</h3>
<div>
<p>Working Groups may be chartered with the agreement of 5% of the W3C membership [<a href="appendices#ref-wg-charter">wg-charter</a>]and the Social Working Group was convened in July 2014<sup><a href="#fn-wg-me">wg-me</a></sup>. One of the W3C Members which helped found the Working Group was the Open Social Foundation, which was a collaboration between several large companies and expected to use their influence to drive participation in the Working Group. The Open Social Foundation dissolved upon the beginning of the Social Web Working Group, handing its assets to W3C [<a href="appendices#ref-wg-os">wg-os</a>].</p>
<p>It is noteworthy that no major social networking companies are members of the W3C Social Web Working Group. Big companies who joined were those motivated primarily by producing social standards for use in business. Many organisations use proprietary, and often in-house, social networking platforms for their employees to communicate, organise, and share information. The benefit of standards in this scenario is to enable inter-organisational social interaction, to better smooth partnership and other business processes. This outlook set the tone for much of the early discussions in the group.</p>
<p>However, over the past two and a half years, active participation in the group has dwindled to such an extent that the group consists of mostly invited experts<sup><a href="#fn-wg-ie">wg-ie</a></sup>. As time progressed, representatives of organisations interested in social business were reassigned and their participation in the group diminished. This dramatically (although it wasn't noticeable at the time) altered the tone of the group.</p>
<p>Several invited experts currently in the Group are representing their own interests, passionate about social standards they can implement for themselves. Others are from open source or free software communities, and want existing or emerging projects to interoperate with regard to social interactions, as a way to add value for users but also to uphold principles of their users' freedom to choose to take their data elsewhere. These two groups are by no means mutually exclusive.</p>
<p>How can Social Web standards possibly be adopted widely enough to have any impact without the support of major social networking platforms? An informal hypothesis by various members of the Working Group is that there are many more (e-)industries who can benefit from social networking than the ones who make advertising- and data-mining-supported social platforms. Such businesses either produce tailored in-house solutions to the very specific corner of social media they need (think Amazon reviews) or embed functionality provided by a major platform (think adding a Facebook Like button). Some have moved all of their publishing and customer interaction to one or more mainstream social networking platforms (some newspapers and magazines; restaurants and cafes). Yet other services have been designed from the ground up to depend on a major platform for the provision of their service at all (marketing and customer analytics software; many games).</p>
<p>Complete dependence is risky, as has been shown on countless occasions when, for example, Twitter changes its developer Terms of Service so that existing third-party applications are suddenly in violation [<a href="appendices#ref-tw-api">tw-api</a>, <a href="appendices#ref-tw-api2">tw-api2</a>, <a href="appendices#ref-tw-api3">tw-api3</a>, <a href="appendices#ref-tw-api4">tw-api4</a>]; or Facebook changes its API, resulting in an endless cycle of unpredictable code maintenance [<a href="appendices#ref-fb-api">fb-api</a>, <a href="appendices#ref-fb-api2">fb-api2</a>].</p>
<p>Depending on centralised platforms for a customer base results in either excluding non-users of the chosen platform, or having to manage a presence on multiple platforms. The circle continues with the availability of services designed to help manage broad social media presence over multiple platforms; these are in the category of social-platform-dependent business models.</p>
<p>Organisations which do not want to depend on existing services tend to have to build their own, creating a burden of storing data (securely and privately) on behalf of their customers when this may not even be central to their business process. Standards which allow their customers to point to a personal data store that they already have would be an advantage in this case.</p>
<p>It is thus organisations for which 'social' is an enhancement (albeit in many cases a critical one) rather than the core of their revenue stream that may be persuaded to invest time in implementing open Web standards. A result of this adoption can contribute towards normalising expectations of more decentralised social interactions from the perspective of end users, too. One could argue that situation with the Social Web is at a maturity level analogous to that of the software industry in the decade before the free software movement was re-launched in the early 1980s.</p>
<p>Unfortunately there has been low participation from this category of organisation as well, so the Working Group has not necessarily managed to appreciate their needs. <!-- Nonetheless, it is not a totally infeasible route to glory. At the very least, it should pique their interest enough to tell us where we got it all wrong and for them to get involved in the next round. Maybe. --></p>
<p>In summary, the Social Web WG specifications are targeted at:</p>
<ul>
<li>individual developers, hobbyists, hackers;</li>
<li>open source projects with principles around data ownership;</li>
<li>companies which enhance their core offering with social functionality;</li>
<li>organisations which produce social systems to facilitate business operations amongst employees.</li>
</ul>
<p>Further, with increasing public awareness of the privacy and freedom implications of handing all data to a select few organisations, these organisations may seek new business models (beyond selling consumer data) and innovate on other fronts in order to retain user trust.</p>
<aside class="note">
<p id="fn-wg-me"><sup>wg-me</sup> One of these was the University of Edinburgh, ie. myself representing my own curiosity at the time, having no idea how deep I'd get. That's right, I joined W3C WGs as a hobby.</p>
<p id="fn-wg-ie"><sup>wg-ie</sup> Invited experts are individuals who cannot pay W3C membership fees but have valuable insight to contribute to a WG. They apply to join, and must be approved by WG chairs.</p>
</aside>
</div>
</section>
<section id="swwg-api-requirements" rel="schema:hasPart">
<h3>API Requirements</h3>
<div>
<p>An early activity of the Working Group was to write 99 "user stories" describing actions that people should be able to carry out using systems based on standards produced by the group. The goal of this was to focus efforts on the most important standards to be worked on, to meet the needs that appeared most critical to members of the group. Most group members contributed one or more user stories, and they varied based on the perspective of the individual or organisation they represented. The group then voted (-1, -0, 0, +0 or +1) on every user story, and selected a top eight to prioritise.</p>
<p>My subsequent contribution was to derive API requirements from the shortlisted user stories.</p>
<section id="swwg-api-requirements-process" rel="schema:hasPart">
<h4>Process</h4>
<div>
<ol>
<li>Read each user story and straightforwardly list required functionality.</li>
<li>Cluster related functionality, find overlap between stories.</li>
<li>Label the clusters.</li>
<li>Organise labels into shortlist of requirements.</li>
</ol>
</div>
</section>
<section id="swwg-api-requirements-results" rel="schema:hasPart">
<h4>Results</h4>
<div>
<p>The simplified story requirements and their respective labels are listed in <a href="#swwg-user-stories">table 12</a>. The labelled requirements, with descriptions derived from the requirements of the combined user stories, are as follows:</p>
<ul id="swwg-api-requirements-list">
<li><strong>Read content</strong> (<span style="background-color: dodgerblue">read</span>): social content should be consumable in a standard way, may be restricted according to the permissions of the viewer, and should be distinguishable by type, author, and associations with groups or other content.</li>
<li><strong>Publish content</strong> (<span style="background-color: lightgreen">pub</span>): users should be able to create, update and delete social content, including metadata, and relationships with other users or content.</li>
<li><strong>Notifications</strong> (<span style="background-color: DarkOrchid">notif</span>): users are alerted when content is created that somehow targets them (ie. as recipient or subject).</li>
<li><strong>Subscribe to content</strong> (<span style="background-color: crimson">sub</span>): users can request notifications about updates certain streams content, eg. by a certain user, posted to a certain group; and users can undo a subscription.</li>
</ul>
<table id="swwg-user-stories">
<caption>Table 12. The top eight Social Web Working Group user stories</caption>
<thead>
<tr>
<th>Story name</th>
<th>Details</th>
<th>Labels</th>
</tr>
</thead>
<tfoot>
<tr><td colspan="3">The first two columns are the work of members of the Social Web Working Group (see wiki history for attribution [<a href="#rdf-swwg-user-stories">swwg-user-stories</a>]) and the third column is my own work.</td></tr>
</tfoot>
<tbody>
<tr>
<td><a href="https://www.w3.org/wiki/Socialwg/Social_API/User_stories#SWAT0">Social Web Acid Test (SWAT0)</a></td>
<td>
<ol>
<li>user A takes a photo of B from their phone and posts it</li>
<li>user A explicitly tags the photo with B</li>
<li>B gets notified that they are in a photo</li>
<li>C who follows A gets the photo</li>
<li>C makes a comment on the photo</li>
<li>A and B get notified of the comment</li>
</ol>
</td>
<td>
<ul>
<li>Publishing a photo. <span style="background-color: lightgreen">pub</span></li>
<li>Push notifications. <span style="background-color: DarkOrchid">notif</span></li>
<li>Subscription to a user. <span style="background-color: crimson">sub</span></li>
<li>Commenting on / replying to a post. <span style="background-color: lightgreen">pub</span></li>
</ul>
</td>
</tr>
<tr>
<td><a href="https://www.w3.org/wiki/Socialwg/Social_API/User_stories#User_posts_a_note">User posts a note</a></td>
<td>
<ol>
<li>Eric writes a short note to be shared with his followers.</li>
<li>After posting the note, he notices a spelling error. He edits the note and re-posts it.</li>
<li>Later, Eric decides that the information in the note is incorrect. He deletes the note.</li>
</ol>
</td>
<td>
<ul>
<li>Publishing text content. <span style="background-color: lightgreen">pub</span></li>
<li>Updating published text. <span style="background-color: lightgreen">pub</span></li>
<li>Deleting published text. <span style="background-color: lightgreen">pub</span></li>
</ul>
</td>
</tr>
<tr>
<td><a href="https://www.w3.org/wiki/Socialwg/Social_API/User_stories#Reading_a_user.27s_recent_posts">Reading a user's recent posts</a></td>
<td>
<ol>
<li>Iris finds a comment by Sam on one of her photos funny. She'd like to read more posts by Sam.</li>
<li>Iris reads the latest notes by Sam. She also reviews his latest photos.</li>
</ol>
</td>
<td>
<ul>
<li>Reading comments / replies. <span style="background-color: dodgerblue">read</span></li>
<li>Reading posts from a particular user. <span style="background-color: dodgerblue">read</span></li>
<li>Viewing photos from a particular user. <span style="background-color: dodgerblue">read</span></li>
</ul>
</td>
</tr>
<tr>
<td><a href="https://www.w3.org/wiki/Socialwg/Social_API/User_stories#Following_a_person">Following a person</a></td>
<td>
<ol>
<li>Delano meets Beth at a company meeting. They are both user interface designers. He finds her ideas interesting.</li>
<li>Delano follows Beth on their company social network.</li>
<li>Beth posts a photo from a whiteboarding session at a company retreat.</li>
<li>Delano sees the photo in his inbox stream.</li>
<li>Ted, Delano's coworker, wants to find new people to follow. He looks at the list of people that Delano follows. He finds Beth in the list, reads her stream, enjoys it, and decides to follow her, too.</li>
<li>Beth posts frequently. Delano is having a hard time reading his inbox stream because Beth's activities drown out everyone else's. He stops following Beth.</li>
</ol>
</td>
<td>
<ul>
<li>Subscription to a user. <span style="background-color: crimson">sub</span></li>
<li>Publishing a photo. <span style="background-color: lightgreen">pub</span></li>
<li>See a user's subscriptions. <span style="background-color: crimson">sub</span></li>
<li>Read posts from a particular user. <span style="background-color: dodgerblue">read</span></li>
<li>Unsubscribe from a user. <span style="background-color: crimson">sub</span></li>
</ul>
</td>
</tr>
<tr>
<td><a href="https://www.w3.org/wiki/Socialwg/Social_API/User_stories#Read_Social_Stream">Read social stream</a></td>
<td>
<ol>
<li>Jake is bored at work. He checks his social inbox stream to see what his friends, family, and coworkers are up to.</li>
<li>Jake sees in his social stream a note by Tammy about her new apartment. Tammy is his friend.</li>
<li>Jake sees in his social stream a photo by Edith from her concert last night. Jake follows Edith but Edith doesn't know Jake. Edith has thousands of followers.</li>
<li>Jake sees in his social stream a video from Damon. Damon and Jake are both in the "Boxing Fans" group. Damon posted the video to the group.</li>
<li>Jake sees in his social stream a sound file from Carol. Carol is Jake's wife. The sound file is a reminder to stop for groceries after work. Carol posted the sound file only for Jake.</li>
<li>Jake sees in his social stream that his friend Tammy has added a new friend, Denise. Jake remembers Denise from high school.</li>
<li>Jake requests to add Denise as a friend, too.</li>
</ol>
</td>
<td>
<ul>
<li>Subscribe to a user (one way). <span style="background-color: crimson">sub</span></li>
<li>Join a group ~= subscribe to group content. <span style="background-color: crimson">sub</span></li>
<li>Publish a video. <span style="background-color: lightgreen">pub</span></li>
<li>Publish audio. <span style="background-color: lightgreen">pub</span></li>
<li>Private sharing. <span style="background-color: dodgerblue">read</span></li>
<li>Publish subscriptions. <span style="background-color: crimson">sub</span></li>
</ul>
</td>
</tr>
<tr>
<td><a href="https://www.w3.org/wiki/Socialwg/Social_API/User_stories#Integration_:_Adding_recommendations_to_bespoke_software">Adding recommendations</a></td>
<td>
<ol>
<li>James maintains an application for managing architectural designs</li>
<li>Maggie, a senior architect would like to recommend many of the better designs</li>
<li>James uses an existing liking service which allows him to post any recommendations, to provide this</li>
<li>This service also allows James to present existing likes for the design in question</li>
<li>Maggie gets to like specific designs, and her followers see these as do viewers of these designs</li>
<li>James achieves this with a simple inclusion on the associated web page, but could have chosen a more detailed integration if greater control was needed over the user interface</li>
</ol>
</td>
<td>
<ul>
<li>Liking / recommending a post. <span style="background-color: lightgreen">pub</span></li>
<li>Subscribe to a user. <span style="background-color: crimson">sub</span></li>
<li>View likes of a post. <span style="background-color: dodgerblue">read</span></li>
<li>Posting from one interface to another system (scope?)</li>
</ul>
</td>
</tr>
<tr>
<td><a href="https://www.w3.org/wiki/Socialwg/Social_API/User_stories#Integration_:_Adding_comments_to_bespoke_software">Adding comments</a></td>
<td>
<ol>
<li>Maria, an IT Architect, has been tasked with encouraging better collaboration on the development of her companies Industrial Processes</li>
<li>As these Processes are tightly controlled (though generally visible) an associated discussion and evangelisation capability is required</li>
<li>Maria integrates with an existing comment capability to store and retrieve comments rather than redeveloping</li>
<li>May-Ling sees the comment area with the Processes and suggests changes, as she herself does not have rights to update</li>
<li>The Process owner gets a notification that someone has commented on this Process</li>
<li>Followers of both the Process owner and May-Ling will see this comment event</li>
<li>Maria achieves this with a simple inclusion on the associated web page, but could have chosen a more detailed integration if greater control was needed over the user interface</li>
</ol>
</td>
<td>
<ul>
<li>Reply to posts. <span style="background-color: lightgreen">pub</span></li>
<li>Notifications. <span style="background-color: DarkOrchid">notif</span></li>
<li>Subscribe to a user. <span style="background-color: crimson">sub</span></li>
<li>Posting from one interface to another system (scope?)</li>
</ul>
</td>
</tr>
<tr>
<td><a href="https://www.w3.org/wiki/Socialwg/Social_API/User_stories#Direct_Messaging">Direct messaging</a></td>
<td>
<ol>
<li>Kyle wants to tell Lisa something privately.</li>
<li>Kyle sends her a message that no one else can view.</li>
<li>Lisa is notified she has a message.</li>
<li>Lisa reads the message and responds privately.</li>
</ol>
</td>
<td>
<ul>
<li>Publishing text content. <span style="background-color: lightgreen">pub</span></li>
<li>Private sharing; specifying audience. <span style="background-color: dodgerblue">read</span></li>
<li>Notifications. <span style="background-color: DarkOrchid">notif</span></li>
</ul>
</td>
</tr>
</tbody>
</table>
</div>
</section>
</div>
</section>
<section id="swwg-competing-specifications" rel="schema:hasPart">
<h3>Competing specifications</h3>
<div>
<p>As this section is concerned with providing insight into the process that resulted in the outcomes of the Social Web Working Group, I will now provide background for a key technical direction that was taken. The work of the Group commenced with some guidelines about deliverables in the charter, but not a specific list; this was something the participants had to figure out in order to meet the previously described API Requirements.</p>
<p>The technologies promoted by active participants of the Working Group settled into roughly three categories: <a href="http://microformats.org/wiki/microformats2">microformats-based</a>, <a href="http://json.org/">JSON-based</a>, and <a href="https://www.w3.org/2001/sw/wiki/RDF">RDF-based</a>, with some small points of overlap. The proponents of JSON-based technologies tended to come from the Open Social Foundation background, with experience in open source social systems designed to support multiple users per server/instance. The microformats supporters brought the perspective of individuals running their own personal implementations of social systems, federating with other individuals on a small scale. The RDF advocates brought experience with large-scale data modelling, open data publishing and data integration, often in an academic or proprietary business context. Producing JSON-based protocols was a requirement of the Working Group charter; the other technologies had the potential to still meet this requirement through the <a href="http://microformats.org/wiki/microformats2-parsing">microformats2 parsing algorithm</a> in the former case, and <a href="https://json-ld.org">JSON-LD</a> in the latter case. These three perspectives are valuable and in theory complementary, but in practice caused drawn out arguments, ideological disagreements, and frequent misunderstandings.</p>
<p>The participants set about bringing their preferred solutions up to standard, and submitted them to the Working Group as Editor's Drafts. I started work on documenting the commonalities between the specifications with the intent that we'd manage to converge them into a single optimal protocol (this is the origin of Social Web Protocols). After many months of work, many hours of telecons, and several face-to-face meetings, technical disagreements and general unwillingness to compromise (all captured for posterity in meeting minutes, mailing list discussions, and GitHub issues) resulted in the convergence effort stalling.</p>
<p>Even leaning on participants' past experiences (see Chapter 4) of prior systems, this was still relatively untrodden ground, so it was never clear (to me, and other more neutral parties) which technology or ideology was most likely to succeed. In most disagreements, it was never obvious that one party was right and the other was wrong. Eventually the Working Group as a whole acknowledged this, and resolved to move forward <em>all</em> of the prospective standards separately, and to stop trying to force convergence.</p>
<p>This decision was controversial in the eyes of other members of the wider W3C community who were not members of Social Web Working Group, and potentially confusing for developers looking for <em>the</em> solution to decentralised Social Web protocols. However the effect was that specification editors stopped arguing about why their way was better, and were free to move their work forward without needing to defend their decisions from people who fundamentally disagreed with their underlying assumptions. Specification editors who had accepted their differences began to help each other, and to share findings and experiences (because they are all working towards the same end goal, after all).</p>
<p>Ultimately the Working Group has a produced a suite of specifications that is not as coherent as it might have been had the participants been united around fundamental technical decisions. However, we also have a better understanding of how to bridge these different perspectives (in terms of writing code, as well as in terms of discussions) than we would have if one perspective had dominated the group and the others had continued their own work elsewhere. Whilst the "glue code" approach is advocated by [<a href="appendices#ref-crit12">crit12</a>], it's too early to tell if this means we increase the chance of these standards being adopted (because we have something to please a broader spectrum of developers out there) or decrease the chances (because we look indecisive and nobody will take the outputs seriously). Similarly, if we see wide uptake of these standards, will we get three (or more) fragmented decentralised Social Webs because developers are opinionated, and writing bridging code is too complicated; or will the efforts towards bridging the approaches be taken up so that completely different protocol stacks can interoperate on some level at least?</p>
<p>The trials and tribulations of the Social Web Working Group have the potential to have far-reaching consequences for the future of the decentralised Social Web, and as such, on how people are able to present and express themselves online. Even if the Working Group's final outputs are not an ultimate solution, the authority given by the W3C standardisation process means that they will at least be referred to, and probably built upon, as the decentralised Social Web grows.</p>
</div>
</section>
<section id="social-web-protocols" rel="schema:hasPart">
<h3>Social Web Protocols</h3>
<div>
<p>Having covered the context of the specifications' development, we now dive into their actual functionality. This section introduces the <em>Social Web Protocols</em>, a description of the specifications produced by the Social Web Working Group, and is arranged by the previously derived API requirements (read, publish, notify, subscribe). Some content in this section is published as a W3C Working Group Note [<a href="appendices#ref-swp">swp</a>]. Systems can be built with these protocols in great variety. Incorporating the standards produced by the Social Web Working Group into a system does not automatically mean the system is empowering to its users; the protocols provide only a skeleton, leaving much open for specialisation by developers. Conformance to these protocols does however imply that users are able to move their data between systems; that clients and servers are somewhat decoupled so users have more flexibility with regards to tools; and that users are not compelled to follow their network or locked into the system where their friends are.</p>
<section id="swp-overview" rel="schema:hasPart">
<h4>Overview</h4>
<div>
<p>People and the content they create are the core components of the Social Web; they make up the social graph. The Social Web Protocols describe standard ways in which people can:</p>
<ul>
<li>connect with other people and subscribe to their content;</li>
<li>create, update and delete social content;</li>
<li>interact with other peoples' content;</li>
<li>be notified when other people interact with their content;</li>
</ul>
<p>regardless of <em>what that content</em> is or <em>where it is stored</em>.</p>
<p>These components are core building blocks for interoperable social systems.</p>
<p>Each of these components can be implemented independently as needed, or all together in one system, as well as extended to meet domain-specific requirements. Users can store their social data across any number of compliant servers, and use compliant clients hosted elsewhere to interact with their own content and the content of others. Put simply, Social Web Protocols tells you, according the recommendations of the Social Web Working Group:</p>
<ul>
<li>how to expose/consume social content (reading).</li>
<li>what to post, and where to, in order to create, update or delete content (publishing).</li>
<li>how to ask for notifications about content (subscribing).</li>
<li>how to deliver notifications about content or users (delivery).</li>
<!-- <li>how to expose profiles and <a href="#relationships">relationships</a>.</li> -->
</ul>
<p>The <a href="#swp-reqs">following table</a> shows the high level requirements according to the <a href="https://www.w3.org/2013/socialweb/social-wg-charter.html">Social Web Working Group charter</a> and the <a href="https://www.w3.org/wiki/Socialwg/Social_API/Requirements">Social API Requirements</a>, and how the specifications of the Working Group overlap with respect to each.</p>
<table id="swp-reqs">
<caption>Table 13. The API requirements and which specs they are met by</caption>
<thead>
<tr>
<th></th>
<th><a href="#content-representation">Vocabulary</a></th>
<th><a href="#content-representation">Syntax</a></th>
<th><a href="#reading">Read</a></th>
<th><a href="#creating-content">Create</a></th>
<th><a href="#updating">Update</a></th>
<th><a href="#deleting">Delete</a></th>
<th><a href="#subscribing">Subscription</a></th>
<th><a href="#delivery">Delivery</a></th>
<!-- <th><a href="#profiles">Profiles</a></th> -->
</tr>
</thead>
<tbody>
<tr>
<td>ActivityPub</td>
<td></td>
<td></td>
<td>X</td>
<td>X</td>
<td>X</td>
<td>X</td>
<td>X</td>
<td>X</td>
<!-- <td>X</td> -->
</tr>
<tr>
<td>ActivityStreams 2.0</td>
<td>X</td>
<td>X</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<!-- <td></td> -->
</tr>
<tr>
<td>Linked Data Notifications</td>
<td></td>
<td></td>
<td>X</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>X</td>
<!-- <td></td> -->
</tr>
<tr>
<td>Micropub</td>
<td></td>
<td></td>
<td></td>
<td>X</td>
<td>X</td>
<td>X</td>
<td></td>
<td></td>
<!-- <td></td> -->
</tr>
<tr>
<td>WebSub</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>X</td>
<td></td>
<!-- <td></td> -->
</tr>
<tr>
<td>Webmention</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>X</td>
<!-- <td></td> -->
</tr>
</tbody>
</table>
<p>The specifications may be implemented alongside each other in various configurations. <a href="#swp-specpaths">Figure 17</a> shows a high level view of how different parties in a social system may be connected together. The arrows show data flowing through the system, and the labels of the arrows are the protocols by which data is enabled to flow.</p>
<figure id="swp-specpaths" rel="schema:hasPart">
<img src="figs/swp.png" id="swp-specpaths-img" />
<figcaption>Figure 17. How the Social Web Protocols specifications connect different (high level) parties together<!-- (<span>all possibilities, click to show different configurations</span>) -->.</figcaption>
</figure>
<p>Some of the specifications overlap in functionality, or complement each other explicitly. This list provides detail on some key relations between different specifications, and <a href="#swp-specrels">table 14</a> provides a summary.</p>
<ul>
<li><strong>ActivityPub and ActivityStreams 2.0</strong>: ActivityPub uses the AS2 syntax and vocabulary for the payload of all requests.</li>
<li><strong>ActivityPub and Linked Data Notifications</strong>: ActivityPub specialises LDN as the mechanism for delivery of notifications by requiring that payloads are AS2. <em>Inbox</em> endpoint discovery is the same. LDN receivers can understand requests from ActivityPub federated servers, but ActivityPub servers can't necessarily understand requests from generic LDN senders.</li>
<li><strong>ActivityStreams 2.0 and Linked Data Notifications</strong>: LDN MAY use the AS2 syntax and vocabulary for the payload of notification requests.</li>
<li><strong>Webmention and Linked Data Notifications</strong>: Overlapping functionality that needs to be bridged due to different content types of requests. An LDN request MAY contain the equivalent data as a Webmention request, but not necessarily vice versa.</li>
<li><strong>ActivityPub and Micropub</strong>: Overlapping functionality that needs to be bridged due to different vocabularies and possibly different content types of requests. Micropub specifies client-to-server interactions for content creation; ActivityPub specifies this, <em>plus</em> side-effects and server-to-server interactions.</li>
<li><strong>Micropub and Webmention</strong>: Are complementary but independent. Content could be created with Micropub, then Webmention discovery can be commenced on any URLs in the content.</li>
<li><strong>Micropub and Linked Data Notifications</strong>: Are complementary but independent. Content could be created with Micropub, then LDN discovery can be commenced on any relevant resources identified by the server.</li>
<li><strong>Micropub and WebSub</strong>: Are complementary but independent. Content could be created with Micropub, then passed to a WebSub <em>hub</em> for delivery to subscribers.</li>
</ul>
<table id="swp-specrels" rel="schema:hasPart">
<caption>Table 14. How each spec relates to the others</caption>
<thead>
<tr>
<th></th>
<th>AS2</th>
<th>AP</th>
<th>MP</th>
<th>LDN</th>
<th>WM</th>
<th>WS</th>
</tr>
</thead>
<tfoot>
<tr>
<td colspan="7">
<p><strong>To read (approx):</strong> if I have <em>x</em>, it uses <em>y</em> to _.</p>
<p><em>n/a</em> means there is no explicit relation between the specs, but does not mean to suggest they can't be used together.</p>
<p><em>bridge</em> means these specs have overlapping functionality and bridging code is needed for interoperability.</p>
</td>
</tr>
</tfoot>
<tbody>
<tr>
<td>AS2</td>
<td></td>
<td>represent content for CRUD, delivery and subscriptions</td>
<td>n/a</td>
<td>MAY represent notification contents</td>
<td>n/a</td>
<td>MAY represent publishers' content</td>
</tr>
<tr>
<td>AP</td>
<td>pass it around with</td>
<td></td>
<td>bridge</td>
<td>use to trigger notifications</td>
<td>n/a</td>
<td>n/a</td>
</tr>
<tr>
<td>MP</td>
<td>n/a</td>
<td>bridge</td>
<td></td>
<td>n/a</td>
<td>n/a</td>
<td>n/a</td>
</tr>
<tr>
<td>LDN</td>
<td>MAY pass notifications around with</td>
<td>use for delivery</td>
<td>n/a</td>
<td></td>
<td>bridge</td>
<td>use for delivery</td>
</tr>
<tr>
<td>WM</td>
<td>n/a</td>
<td>n/a</td>
<td>n/a</td>
<td>bridge</td>
<td></td>
<td>n/a</td>
</tr>
<tr>
<td>WS</td>
<td>MAY pass feeds to subscribers</td>
<td>n/a</td>
<td>n/a</td>
<td>use to trigger notifications</td>
<td>n/a</td>
<td></td>
</tr>
</tbody>
</table>
</div>
</section>
<section id="swp-read" rel="schema:hasPart">
<h4>Reading</h4>
<div>
<p>An individual's self presentation online can be partially composed of content they produce and interact with. The <em>read</em> label covers how these are exposed for consumption by others. This may include permissions or access control, which could require the reader to identify themselves before content is made available. Different types of content and interactions should be discoverable, perhaps according to criteria like the type of content, a group or individual with which it is associated, or through its association with other content (eg. through replies).</p>
<section id="content-representation">
<h5>Content representation</h5>
<div>
<p><strong>ActivityStreams 2.0</strong> (AS2) models content and interactions as objects and activities. AS2 includes a <em>vocabulary</em> for modelling different types of objects and activities as well as various relations they might have with other objects (including user profiles) and activities. The AS2 <em>syntax</em> describes a consistent structure for objects and activities including sets of objects and activities as collections. Collections can be explicitly created and updated by a user (like adding photos to an album) or generated automatically as a result of other user actions or the properties of certain objects/activities (eg. a list of followers of a user). AS2 does not specify how objects, activities, or collections come into existence, only what they look like once they do.</p>
<p>AS2 content must be served with the Content-Type <code>application/activity+json</code> or, if necessary for JSON-LD extended implementations, <code>application/ld+json; profile="https://www.w3.org/ns/activitystreams"</code>. Content must be described using the AS2 vocabulary, and may use other vocabularies in addition or instead, per the extension mechanism.</p>
<p>To make content available as ActivityStreams 2.0 JSON, one could do so directly when requested with an appropriate <code>Accept</code> header (eg. <code>application/activity+json</code> or <code>application/ld+json</code>), or indirectly via a <code>rel="alternate" type="application/activity+json"</code> link . This link could be to a different domain, for third-party services which dynamically generate ActivityStreams 2.0 JSON on behalf of a publisher.</p>
<p>AS2 builds upon ActivityStreams 1.0 [<a href="appendices#ref-as1">as1</a>] and is not fully backwards compatible; <a href="http://www.w3.org/TR/activitystreams-core#activitystreams-1.0">the relationship between AS1 and AS2 is documented in the AS2 spec</a>.</p>
<p>Because AS2 is a data model, it does not recommend how data should be displayed. Its utility is in enabling a consistent representation of social objects and activities to be passed between potentially disconnected systems (eg. from Alice's social network to Bob's). The systems consuming the data are responsible for rendering it appropriately. This means that system designers can provide their users with options for customising the presentation data that may constitute their profiles.</p>
</div>
</section>
<section id="extending-as2">
<div>
<h5>Extending AS2</h5>
<p>AS2 specifies a finite set of object and activity types and properties. These are a baseline set of common social interactions which can be extended upon by systems which need additional terms or more specific variations. The extension mechanism is based on Linked Data, via JSON-LD. Developers are expected to publish documentation and an RDF representation of their terms at a domain under their control, and refer to terms by URI in the normal manner. Further, the Social Web Working Group describes a mechanism by which well-used extensions are included with the AS2 namespace document by means of a W3C Community Group vetting process. The advantage of this is that implementations can adopt common extensions easily, without needing to include additional namespaces. It also makes extensions more discoverable for newcomers to AS2.</p>
<p>The first such extension is in fact <strong>ActivityPub</strong>. ActivityPub uses ActivityStreams 2.0 for all data in all requests, and also adds additional terms to the AS2 namespace. Thus, ActivityPub requires requests have the Content-Type <code>application/ld+json; profile="https://www.w3.org/ns/activitystreams"</code>.</p>
</div>
</section>
<section id="content-representation-other">
<h5>Other ways of representing content</h5>
<div>
<p>Despite AS2 being the recommended syntax and vocabulary of the Working Group, some specifications use different or broader mechanisms. This helps to let developers pick and choose different specifications for different tasks even if they prefer not to use AS2:</p>
<ul>
<li><strong>Linked Data Notifications</strong> notification contents can use any vocabulary, so long as the data is available in JSON-LD. Thus notifications may use ActivityStreams 2.0, but don't have to. Clients and servers can negotiate between themselves (using <code>Accept</code> and <code>Accept-Post</code> HTTP headers) about using different RDF syntaxes, as well.</li>
<li><strong>Micropub</strong> clients which expect to read data (this would usually be clients for <em>updating</em> content) are expecting it as JSON in the <a href="http://microformats.org/wiki/microformats2-parsing">parsed microformats2 syntax</a>.</li>
<li><strong>WebSub</strong> is agnostic as to the Content-Type used by publishers; hubs are expected to deliver the new content to subscribers as-is produced by the publisher, at the publisher's <code>topic</code> URL.</li>
</ul>
</div>
</section>
<section id="objects-and-streams">
<h5>Objects and streams</h5>
<div>
<p>Whichever syntax and vocabulary is used, there are some general recommendations for representing objects (individual entities) and streams (sets or collections of objects).</p>
<ul>
<li>All objects must have URLs in their <code>id</code> property. This URL should resolve to return the properties of an object; what is returned may depend on the requester's right to access the content, determined by authentication and/or authorisation.</li>
<li>Each stream must have a URL, which must resolve to return the contents of the stream (according to the requester's right to access, and could be paged). The data returned may include additional metadata about the stream (such as title, description).</li>
<li>Each object in a stream must contain at least its URL, which can be dereferenced to retrieve all properties of the object, and may contain other properties of the object.</li>
<li>One user may publish one or more streams of content. Streams may be generated automatically or manually, and might be segregated by post type, topic, audience, or any arbitrary criteria decided by the curator of the stream. A user <a href="#profiles">profile</a> MAY include links to multiple streams, which a consumer could follow to read or subscribe to.</li>
</ul>
</div>
</section>
<section id="special-streams">
<h5>Special streams</h5>
<div>
<p>Streams are represented in AS2 as a <code>Collection</code> or <code>OrderedCollection</code>. ActivityPub defines some special usages; two streams that must be accessible from a user's profile, and four which are optional, via the following properties:</p>
<ul>
<li><code>inbox</code>: A reference to an AS2 collection comprising all the objects sent to the profile's owner.</li>
<li><code>outbox</code>: An AS2 collection comprising all the objects produced by the profile's owner.</li>
<li><code>following</code>: An optional AS2 collection of the users that this user is following.</li>
<li><code>followers</code>: An optional AS2 collection of the users that follow this user.</li>
<li><code>likes</code>: An optional AS2 collection of every <code>object</code> from all of the user's <code>Like</code> activities (generated automatically by the server).</li>
<li><code>streams</code>: An optional list of supplementary AS2 collections which may be of interest. </li>
</ul>
<p>ActivityPub permits arbitrary streams to be updated through specifying special behavior for the server when it receives activities with types <code>Add</code> and <code>Remove</code>. When a server receives such an activity in the <code>outbox</code>, and the <code>target</code> is a stream, it must add the <code>object</code> to the <code>target</code> (for <code>Add</code>) or remove the <code>object</code> from the <code>target</code> (for <code>Remove</code>).</p>
<p>Two kinds of special streams are <code>inbox</code> and <code>outbox</code>. When read (ie. with an HTTP <code>GET</code> request) they return ordinary streams of objects, but they also double as endpoints which can be <code>POST</code>ed to directly to add objects, for <a href="#swp-delivery">delivery of notifications</a> and <a href="#swp-publish">publishing new content</a> respectively.</p>
<p>The <code>inbox</code> is a notion shared by ActivityPub and Linked Data Notifications, however in order to be <em>read</em> by both ActivityPub <em>and</em> LDN clients, publishers must relate the stream to the objects it contains using both the <code>as:items</code> and <code>ldp:contains</code> predicates. This is an unfortunate discord, but since ActivityPub is immovably tied to AS2 and LDN is immovably tied to compatibility with the vocabulary of existing Linked Data Platform servers, there was really no compromise to be had. Fortunately this bridge is relatively minor in terms of coding, once a developer is aware of it.</p>
</div>
</section>
</div>
</section>
<section id="swp-publish" rel="schema:hasPart">
<h4>Publishing</h4>
<div>
<p>Publishing in this context incorporates creating new content, and updating or deleting existing content. The ability to publish content and generate (and update or remove) new data is critical to online self-presentation, in particular it is part of <strong>customisability</strong> in building an online profile.</p>
<p>Content generated through a client (such as a web form, mobile app, sensor, smart device) is created when it is sent to a server for processing, where it is typically stored and usually published (either publicly or to a restricted audience, in human- and/or machine-readable forms). Clients and servers may independently support creating, updating and deleting; there are no dependencies between them.</p>
<p>Authentication and authorization between clients and servers for creating content are not included in these specifications, as they are considered orthogonal problems which should be solved elsewhere.</p>
<p>The two specifications recommended by the Social Web Working Group for publishing are Activitypub and Micropub. They use similar high level mechanisms, but differ in requirements around both the vocabularies and content types of data. ActivityPub contains a client-to-server API for creating ActivityStreams 2.0 objects and activities, and specifies additional responsibilities for clients around addressing objects, and for servers around the side-effects of certain types of objects. Micropub provides a basic client-to-server API for creating blog-post type content which can be implemented alone and is intended as a quickstart for content creation, on top of which more complex (but optional) actions can be layered.</p>
<p>Both provide similar media endpoints for uploading files.</p>
<p>Neither ActivityPub nor Micropub define APIs for publishing based on HTTP verbs, and thus differ from the more RESTful <a href="https://www.w3.org/TR/ldp">Linked Data Platform (LDP)</a>.</p>
<section id="swp-creating">
<h5>Creating</h5>
<div>
<p>The publishing endpoint of <strong>ActivityPub</strong> is the <code>outbox</code>. Clients are assumed to have the URL of a (ideally authenticated) user profile as a starting point, and discover the value of the <code>https://www.w3.org/ns/activitystreams#outbox</code> property found at the profile URL (which should be available as JSON[-LD]). The client then makes an HTTP <code>POST</code> request with an ActivityStreams 2.0 activity or object as a JSON[-LD] payload with a content type of <code>application/ld+json; profile="https://www.w3.org/ns/activitystreams"</code>. The URL of the created resource is generated at the discretion of the server, and returned in the <code>Location</code> HTTP header. This is an appropriate protocol to use when:</p>
<ul>
<li>You want to send/receive a JSON or JSON-LD payload.</li>
<li>Your data is described with AS2 (optionally extensible via JSON-LD).</li>
<li>You want serves to carry out a known set of actions upon content creation.</li>
</ul>
<p>Side-effects of creating content with ActivityPub are for the most part adding things to various different collections collections (likes, follows, etc); but also include requirements about blocking users, and a hook to enable federated servers.</p>
<p>The publishing endpoint for <strong>Micropub</strong> is the <code>micropub</code> end point. Clients discover this from a user's URL via a <code>rel="micropub"</code> link (in an HTTP <code>Link</code> header, or an HTML element). Clients make a <code>x-www-form-urlencoded</code> POST request containing the key-value pairs for the attributes of the object being created. The URL of the created resource is generated at the discretion of the server, and returned in the <code>Location</code> HTTP header. Clients and servers must support attributes from the Microformats 2 h-entry vocabulary. Micropub also defines special reserved attributes (prefixed with <code>mp-</code>) which can be used as commands to the server. Any additional key names sent outside of these vocabularies may be ignored by the server.</p>
<p>Micropub requests may alternatively be sent as a JSON payload, the syntax of which is derived from the Microformats 2 parsing algorithm. This is an appropriate protocol to use when:</p>
<ul>
<li>You want to send/receive a form-encoded or JSON payload.</li>
<li>Your data is described with the h-entry syntax and vocabulary.</li>
<li>You can rely on out-of-band agreements between clients and servers for vocabulary extensibility.</li>
</ul>
</div>
</section>
<section id="swp-updating">
<h5>Updating</h5>
<div>
<p>Content is updated when a client sends changes to attributes (additions, removals, replacements) to an existing object. If a server has implemented a <a href="#swp-delivery">delivery</a> or <a href="#swp-subscribing">subscription</a> mechanism, when an object is updated, the update MUST be propagated to the original recipients using the same mechanism.</p>
<p><strong>ActivityPub</strong> clients send an HTTP <code>POST</code> request to the <code>outbox</code> containing an AS2 <code>Update</code> activity. The <code>object</code> of the activity is an existing object, and the fields to update should be nested. If a partial representation of an object is sent, omitted fields are <em>not</em> deleted by the server. In order to delete specific fields, the client can assign them a <code>null</code> value. However, when a federated server passes an <code>Update</code> activity to another server's <em><code>inbox</code></em>, the recipient must assume this is the <em>complete</em> object to be replaced; partial updates are not performed server-to-server.</p>
<p><strong>Micropub</strong> clients perform updates, as either form-encoded or JSON POST requests, using the <code>mp-action=update</code> parameter, as well as a <code>replace</code>, <code>add</code> or <code>delete</code> property containing the updates to make, to the Micropub endpoint. <code>replace</code> replaces all values of the specified property; if the property does not exist already, it is created. <code>add</code> adds new values to the specified property without changing the existing ones; if the property does not exist already, it is created. <code>delete</code> removes the specified property; you can also remove properties by value by specifying the value.</p>
</div>
</section>
<section id="swp-deleting">
<h5>Deleting</h5>
<div>
<p>Content is deleted when a client sends a request to delete an existing object. If a server has implemented a <a href="#delivery">delivery</a> or <a href="#subscribing">subscription</a> mechanism, when an object is deleted, the deletion MUST be propagated to the original recipients using the same mechanism.</p>
<p><strong>ActivityPub</strong> clients delete an object by sending an HTTP POST request containing an AS2 <code>Delete</code> activity to the <code>outbox</code> of the authenticated user. Servers MUST either <em>replace</em> the <code>object</code> of this activity with a tombstone and return a <code>410 Gone</code> status code, or return a <code>404 Not Found</code>, from its URL.</p>
<p><strong>Micropub</strong> delete requests are two key-value pairs, in form-encoded or JSON: <code>mp-action</code>: <code>delete</code> and <code>url</code>: <code>url-to-be-deleted</code>, sent to the Micropub endpoint .</p>
</div>
</section>
</div>
</section>
<section id="swp-subscribing" rel="schema:hasPart">
<h4>Subscribing</h4>
<div>
<p>An agent (client or server) may <em>ask</em> to be notified of changes to a content object (eg. edits, new replies) or stream of content (eg. objects added or removed from a particular stream). This is <em>subscribing</em>. This is part of the process of creating links between individuals in a social network, and other individuals or resources; part of <strong>connectivity</strong>. Specifications which contain subscription mechanisms are ActivityPub and WebSub.</p>
<p>Nothing should rely on implementation of a subscription mechanism. That is, implementations may set themselves up to receive notifications without always being required to explicitly ask for them from a sender or publisher: see <a href="#swp-delivery">delivery</a>.</p>
<section id="swp-follow">
<h5>Subscribing with <code>as:Follow</code></h5>
<div>
<p><strong>ActivityPub</strong> servers maintain a <em>Followers</em> collection for all users. This collection may be directly addressed, or addressed automatically or by default, in the <code>to</code>, <code>cc</code> or <code>bcc</code> field of any Activity, and as a result, servers <a href="#swp-delivery">deliver</a> the Activity to the <code>inbox</code> of each user in the collection.</p>
<p>Subscription requests are essentially requests to be added to this collection. They are made by the subscriber's server <code>POST</code>ing a <code>Follow</code> Activity to the target's <code>inbox</code>. This request should be authenticated, and therefore doesn't need additional verification. The target server then SHOULD add the subscriber to the target's Followers collection. Exceptions may be made if, for example, the target has blocked the subscriber.</p>
<p>This is a suitable subscription mechanism when:</p>
<ul>
<li>The subscriber wants to request updates from a specific actor (rather than objects, streams or threads).</li>
<li>The subscriber and publisher both speak ActivityStreams 2.0.</li>
<li>The publisher is aware of who has subscribed, and capable of delivering content to subscribers itself.</li>
</ul>
<p>Since delivery is only a requirement for federated servers, prospective subscribers will not be able to <code>POST</code> their <code>Follow</code> activity to the <code>inbox</code> of a profile which is on a non-federated server (expect a <code>405 Method Not Allowed</code>), and thus are not able to subscribe to these profiles. In this case, prospective subscribers may wish to periodically <em>pull</em> from the publisher's <code>outbox</code> instead.</p>
</div>
</section>
<section id="subscription-delegating">
<h5>Delegating subscription handling</h5>
<div>
<p><strong>WebSub</strong> provides a mechanism to delegate subscription handling and delivery of content to subscribers to a third-party, called a <em>hub</em>. All publishers need to do is link to their chosen hub(s) using HTTP <code>Link</code> headers or HTML <code><link> </code> elements with <code>rel="hub"</code>, and then notify the hub when new content is available. The mechanism for notifying the hub is left deliberately unspecified, as publishers may have their own built in hub, and therefore use an internal mechanism.</p>
</div>
</section>
<p>Hubs and publishers which would like to agree on a standard mechanism to communicate might consider employing an existing <a href="#swp-delivery">delivery</a> mechanism, namely Linked Data Notifications (<a href="#swp-subscription-notification">fig. [subscription-notification</a>]) or Webmention<sup><a href="#fn-swp-sub-wm">sub-wm</a></sup>.</p>
<figure id="swp-subscription-notification" class="listing">
<pre><code>POST /inbox HTTP/1.1</code>
<code>Host: hubbub.example</code>
<code>Content-type: application/ld+json</code>
<code></code>
<code>{</code>
<code> "@context": "https://www.w3.org/ns/activitystreams",</code>
<code> "id": "",</code>
<code> "type": "Announce",</code>
<code> "object": "https://rhiaro.co.uk/tags/socialwg",</code>
<code> "target": "https://hubbub.example/"</code>
<code>}</code></pre>
<figcaption>Notifying a hub of new content with LDN, using an AS2 Announce in the notification body. The <code>object</code> is the <code>topic</code> URL and the <code>target</code> is the hub itself. The hub can use this information to fetch new content for subsequent delivery to subscribers.</figcaption>
</figure>
<p>The subscriber discovers the hub from the publisher, and sends a form-encoded <code>POST</code> request containing values for <code>hub.mode</code> ("subscribe"), <code>hub.topic</code> (the URL to subscribe to) and <code>hub.callback</code> (the URL where updates should be sent to, which should be 'unguessable' and unique per subscription). The hub and subscriber carry out a series of exchanges to verify this request.</p>
<p>When the hub is notified of new content by the publisher, the hub fetches the content of the <code>topic</code> URL, and <a href="#swp-delivery">delivers</a> this to the subscriber's <code>callback</code> URL.</p>
<p>This is a suitable subscription mechanism when:</p>
<ul>
<li>The subscriber wants to request updates from any resource (not just user profiles), and of any content type.</li>
<li>Subscription requests are not authenticated, so you need a way to verify them.</li>
<li>The publisher wants to delegate distribution of updates to another service (the hub) instead of doing it itself.</li>
</ul>
</div>
<p>LDN Receivers can receive deliveries from WebSub hubs by using the <code>inbox</code> URL as the <code>hub.callback</code> URL and <em>either</em> only subscribing to resources published as JSON-LD <em>or</em> accepting content-types other than JSON-LD.</p>
<aside class="note">
<p id="fn-swp-sub-wm"><sup>swp-sub-wm</sup> though this seems to be me to be somewhat outside of the spirit of 'mentioning'.</p>
</aside>
</section>
<section id="swp-delivery" rel="schema:hasPart">
<h4>Delivering</h4>
<div>
<p>A user or application may wish to push a notification to another user that the receiver has <em>not explicitly asked</em> for. For example to send a message or some new information; because they have linked to (replied, liked, bookmarked, reposted, etc) their content; because they have linked to (tagged, addressed) the user directly; to make the recipient aware of a change in state of some document or resource on the Web. This is also part of <strong>connectivity</strong>, as well as a potential way to make individuals aware of how their content is <strong>cascade</strong>d throughout a network, and how they are connected to others of whom they were previously unaware. The Social Web Working Group specifications contain several mechanisms for carrying out delivery; they are listed here from general to specialsed.</p>
<section id="swp-targeting-and-discovery">
<h5>Targeting and discovery</h5>
<div>
<p>The target of a notification is usually the addressee or the subject, as referenced by a URL. The target may also be someone who has previously requested notifications through a <a href="#subscribing">subscription</a> request. Once you have determined your target, you need to discover where to send the notification for that particular target. Do this by fetching the target URL and looking for a link to an endpoint which will accept the type of notification you want to send (read on, for all of your exciting options).</p>
<p>Bear in mind that many potential targets will <em>not</em> be configured to receive notifications at all. To avoid overloading unsuspecting servers with discovery-related requests, your application should employ a "back-off" strategy when carrying out discovery multiple times to targets on the same domin. This could involve increasing the period of time between subsequent requests, or caching unsuccessful discovery attempts so those domains can be avoided in future. You may wish to send a <code>User-Agent</code> header with a reference to the notification mechanism you are using so that recipient servers can find out more about the purpose of your requests.</p>
<p>Your application should also respect relevant cache control and retry headers returned by the target server.</p>
</div>
</section>
<section id="swp-delivery-generic">
<h5>Generic notifications</h5>
<div>
<p><strong>LDN</strong> provides a protocol for sending, receiving and consuming notifications which may contain any content, or be triggered by any person or process. Senders, receivers and consumers can all be on different domains, thus this meets the criteria for a federation protocol. This is a suitable notification mechanism when:</p>
<ul>
<li>Notifications need to be identifiable with their own URLs and exposed by the receiver for other applications to discover and re-use.</li>
<li>Notifications are represented as a JSON-LD payload (ie. a 'fat ping').</li>
<li>You need to advertise constraints on the type or contents of notifications accepted by a receiver.</li>
</ul>
<p>LDN functionality is divided between <em>senders</em>, <em>receivers</em> and <em>consumers</em>. The endpoint to which notifications are sent is the <code>inbox</code>. Any resource (a user profile, blog post, document) can advertise its <code>inbox</code> so that it may be discovered through an HTTP <code>Link</code> header or the document body in any RDF syntax (including JSON-LD or HTML+RDFa). To this Inbox, senders make a <code>POST</code> request containing the JSON-LD (or other RDF syntax per <code>Accept-Post</code> negotation with the receiver) payload of the notification. The receiver returns a URL from which the notification data can be retrieved, and also adds this URL to a list which is returned upon a <code>GET</code> request to the Inbox. Consumers can retrieve this Inbox listing, and from there the individual notifications, as JSON-LD (optionally content negotiated to another RDF syntax). An obvious type of consumer is a script which displays notifications in a human-readable way.</p>
<p>An existing LDP implementation can serve as an LDN receiver; publishers simply advertise any <code>ldp:Container</code> as the <code>inbox</code> for a resource.</p>
<p>The payload of notifications is deliberately left open so that LDN may be used in a wide variety of use cases. However, receivers with particular purposes are likely to want to constrain the types of notifications they accept. They can do this transparently (such that senders are able to attempt to conform, rather than having their requests rejected opaquely) by advertising data shapes constraints such as <a href="https://www.w3.org/TR/shacl/">SHACL</a>. Advertisement of such constraints also allows consumers to understand the types of notifications in the Inbox before attempting to retrieve them. Receivers may reject notifications on the basis of internal, undisclosed constraints, and may also access control the Inbox for example by requiring an <code>Authorization</code> header from both senders and consumers.</p>
<p><strong>WebSub</strong> <em>publishers</em> deliver content to their <em>hub</em>, and <em>hubs</em> to their <em>subscribers</em> using HTTP <code>POST</code> requests. The body of the request is left to the discretion of the sender in the first case, and in the latter case must match the Content-Type of and contain contents from the <code>topic</code> URL.</p>
</div>
</section>
<section id="delivery-activities">
<h5>Activity notifications</h5>
<div>
<p><strong>ActivityPub</strong> uses LDN to send notifications with some specific constraints. These are:</p>
<ul>
<li>The notification payload MUST be a single AS2 Activity.</li>
<li>The notification payload MUST be compact JSON-LD.</li>
<li>The receiver MUST verify the notification by fetching its source from the origin server.</li>
<li>All notification <code>POST</code> requests are authenticated.</li>
</ul>
<p>ActivityPub specifies how to define the <em>target(s)</em> to which a notification is to be sent (a pre-requisite to LDN sending), via the AS2 audience targeting and object linking properties.</p>
<p>ActivityPub also defines side-effects that must be carried out by the server as a result of notification receipt. These include:</p>
<ul>
<li>Creating, updating or deleting new objects upon receipt of <code>Create</code>, <code>Update</code> and <code>Delete</code> activities.</li>
<li>Reversing the side-effects of prior activities upon receipt of the <code>Undo</code> activity.</li>
<li>Updating specialised collections for <code>Follow</code>, <code>Like</code> and <code>Block</code> activities.</li>
<li>Updating any other collections upon receipt of <code>Add</code> and <code>Remove</code> activities.</li>
<li>Carrying out further delivery to propagate activities through the network in the case of federated servers.</li>
</ul>
<p>ActivityPub actor profiles are linked to their inboxes via the <code>https://www.w3.org/ns/activitystreams#inbox</code> property. This is an <em>alias</em> (in the AS2 JSON-LD context) for LDN's <code>http://www.w3.org/ns/ldp#inbox</code>. Applications using a full JSON-LD processor to parse these documents will see these terms as one and the same. Applications doing naive string matching on terms may wish to note that if you find an <code>ldp:inbox</code> it will accept <code>POST</code> requests in the same way as an <code>as:inbox</code>.</p>
</div>
</section>
<section id="delivery-mentioning">
<h5>Mentioning</h5>
<div>
<p><strong>Webmention</strong> provides an API for sending and receiving notifications when a relationship is created between two documents by including the URL of one document in the content of another. It works when the two documents are on different domains, thus serving as a federation protocol. This is a suitable notification mechanism when:</p>
<ul>
<li>You have a document (source) which contains the URL of another document (target).</li>
<li>The owner of the endpoint has access to view the source (so the request can be verified).</li>
<li>The only data you need to send over the wire are the URLs of the source and target documents (ie. a 'thin ping').</li>
</ul>
<p>There are no constraints on the syntax of the source and target documents. Discovery of the Webmention endpoint (a script which can process incoming webmentions) is through a link relation (<code>rel="webmention"</code>), either in the HTTP <code>Link</code> header or HTML body of the target. This endpoint does not need to be on the same domain as the target, so webmention receiving can be delegated to a third party.</p>
<p>Webmentions are verified by the server dereferencing the source and parsing it to check for the existence of the target URL. If the target URL isn't found, the webmention MUST be rejected.</p>
<p>Webmention uses <code>x-www-form-urlencoded</code> for the source and target as parameters in an HTTP POST request. Beyond verification, it is not specified what the receiver should do upon receipt of a Webmention. What the webmention endpoint should return on a <code>GET</code> request is also left unspecified.</p>
</div>
</section>
<section id="delivery-interop">
<h5>Delivery interop</h5>
<div>
<p>This section describes how receiver implementations of either Webmention or LDN may create bridging code in order to accept notifications from senders of the other. This can also be read to understand how a sender of either Webmention or LDN should adapt their discovery and payload in order to send to a receiver of the other.</p>
<p><strong>Webmention receivers</strong> wishing to also accept LDN <code>POST</code>s at their Webmention endpoint MUST:</p>
<ul>
<li>Advertise the webmention endpoint via <code>rel="http://www.w3.org/ns/ldp#inbox"</code> in addition to <code>rel="webmention"</code> (in the <code>Link</code> header, HTML body or JSON body of a target).</li>
<li>Accept <code>POST</code> requests with the Content-Type <code>application/ld+json</code>. Expect the body of the request to be:
<figure class="listing">
<pre><code>{</code>
<code> "@context": "http://www.w3.org/ns/webmention#",</code>
<code> "@id": "",</code>
<code> "source": { "@id": "https://waterpigs.example/post-by-barnaby" },</code>
<code> "target": { "@id": "https://aaronpk.example/post-by-aaron" }</code>
<code>}</code></pre></figure>
</li>
<li>Use the <code>source->@id</code> and <code>target->@id</code> values as the <code>source</code> and <code>target</code> of the Webmention, and proceed with verification.</li>
<li>If returning a <code>201 Created</code>, it MUST return a <code>Location</code> header with a URL from which the contents of the request posted can be retrieved. <code>202 Accepted</code> is still fine.</li>
<li>Note than when verifying the source, there's a good chance you can request/parse it as RDF.</li>
</ul>
<p><strong>LDN receivers</strong> wishing to also accept Webmentions to their Inbox MUST:</p>
<ul>
<li>Advertise the Inbox via <code>rel="webmention"</code> in addition to <code>rel="http://www.w3.org/ns/ldp#inbox"</code> (in the <code>Link</code> header, HTML body or JSON body of a target).</li>
<li>Accept <code>POST</code> requests with a content type <code>application/x-www-form-urlencoded</code>. Convert these requests from:
<figure class="listing">
<pre><code>source=https://waterpigs.example/post-by-barnaby&
target=https://aaronpk.example/post-by-aaron</code></pre>
</figure>
to:
<figure class="listing">
<pre><code>{</code>
<code> "@context": "http://www.w3.org/ns/webmention#",</code>
<code> "@id": "",</code>
<code> "source": { "@id": "https://waterpigs.example/post-by-barnaby" },</code>
<code> "target": { "@id": "https://aaronpk.example/post-by-aaron" }</code>
<code>}</code></pre>
</figure>
and proceed per LDN; receivers MAY add other triples at their discretion.
</li>
<li>Receivers MUST return a <code>201 Created</code> with a <code>Location</code> header or <code>202 Accepted</code>.</li>
<li>Receivers MUST verify the request by retrieving the source document and checking a link to the target document is present. If the Webmention is not verified, recievers MUST NOT keep it.</li>
</ul>
</div>
</section>
<section id="wm-as-as">
<h5>Webmention as AS2</h5>
<div>
<p>A webmention may be represented as a persistent resource with AS2. This could come in handy if a Webmention sender <em>mentions</em> a user known to be running an ActivityPub federated server. In this case, the sender can use an AS2 payload and carry out <a href="#delivery">delivery</a> of the notification per ActivityPub/LDN.</p>
<figure class="listing">
<pre><code>{</code>
<code> "@context": "https://www.w3.org/ns/activitystreams#",</code>
<code> "type": "Relationship",</code>
<code> "subject": "https://waterpigs.example/post-by-barnaby",</code>
<code> "object": "https://aaronpk.example/post-by-aaron"</code>
<code>}</code></pre>
</figure>
<p>A receiver or sender may want to augment this representation with the relationship between the two documents, and any other pertinent data. In the receiver's case, this could be gathered when they parse the source during the verification process. For example:</p>
<figure class="listing">
<pre><code>{</code>
<code> "@context": "https://www.w3.org/ns/activitystreams#",</code>
<code> "type": "Relationship",</code>
<code> "subject": {</code>
<code> "id": "https://waterpigs.example/post-by-barnaby",</code>
<code> "name": "Hi Aaron, great post."</code>
<code> },</code>
<code> "object": {</code>
<code> "id": "https://aaronpk.example/post-by-aaron",</code>
<code> "name": "Aaron's first post."</code>
<code> },</code>
<code> "relationship": "inReplyTo"</code>
<code>}</code></pre>
</figure>
</div>