# Copyright (c) 2024-2025 Philipp Schafft

# licensed under Artistic License 2.0 (see LICENSE file)

# ABSTRACT: Work with Tag databases
# PODNAME: Data::TagDB::Tutorial::Conventions

__END__

=pod

=encoding UTF-8

=head1 NAME

Data::TagDB::Tutorial::Conventions - Work with Tag databases

=head1 VERSION

version v0.11

=head1 Overview

This documentation outlines basic conventions that have been establish when working with universal tag data.
Most of this document applies to the creation of tags.

It must be noted that the conventions outlined in this documentation are one of many ways. However they are
selected as they give a very good compatibility with other existing data structures, patterns, and conventions.

=head2 Meaning of a tag

Each tag forms an inseparably pair with exactly one subject.
The represents exactly this B<one subject>.
And each subject is represented by exactly B<one tag>.

As tag and subject form this tight atomic bond they are often used synonymous.

=head2 Abstract and specific

A subject can be one of I<abstract>, a concept, or I<specific>, an instances of a concept or neither nor.

An I<abstract> subject is always untouchable, a kind, or genre of things. Examples include the concept of books, or
the concept of parentship. In software development they are often called I<types>.

A I<specific> subject is an I<instance> of one or more I<abstract> subjects. Examples include
any specific book one can I<touch>, or the specific relation between a specific parent and child.

B<Note:>
The concept of touchableness is to be understood figuratively here. For example "I<air>" (our atmosphere) is often considered untouchable,
while the atmosphere is still I<specific> (touchable).

=head3 Tag definition and merging

Any two tags that represent the same subject are in fact the same tag. If they occur in software they can be (and should)
be merged.

However, which subject a tag belongs to is given by it's definition. Definitions by different parties
(or even by the same party over time, e.g. different versions of a standard) will differ.
In those cases tags must not be merged.

This also implies that if for example a standard updates the definition of a tag it must create a new tag
(most often denoted by a new identifier for the new tag).

=head1 Tag identification

=head2 Tag identifiers

Each tag is identified by a set of zero or more identifiers.
Identifiers can be of different I<types>. Each type has it's own specific properties.
Each tag should have at least one globally unique identifier, often an UUID.

See also L<Data::TagDB::Tutorial::WellKnown/also-shares-identifier>.

=head3 ISE identifiers

It is recommended that each tag should have an UUID, an OID, or an URI (in that order of preference) that identifies the tag.
Those types have several properties that make them good identifiers:

=over

=item *

Each of those types can be serialised using I<ISE> (Identifier String Encoding)

=item *

All UUIDs can be converted to both OIDs and URIs.

=item *

All OIDs can be converted to URIs.
OIDs that have been UUIDs before can be converted back into their normal form as UUID.

=item *

URIs that have been UUIDs or OIDs can be converted back into their normal form as UUID, or OID.

=item *

All three types support globally unique identifiers.

=item *

Each of the types has it's own special properties complementing each other.

=back

B<Note:>
URIs here are understood as identifiers for tags. This is not to be confused with
URIs (most often URLs) used to locate specific documents (for I<fetching> them).
It is generally expected that fetching any URI used as an identifier will result
in error or a document being fetched that is different from the tag's subject.

See also
L<Data::TagDB::Tutorial::WellKnown/uuid>,
L<Data::TagDB::Tutorial::WellKnown/oid>,
L<Data::TagDB::Tutorial::WellKnown/uri>.

=head2 Tag names

Tag names are specific identifiers of the type I<tagname> (see L<Data::TagDB::Tutorial::WellKnown/tagname>).
They provide a basic way to name a tag. However they are not to be confused with proper names, or document titles
or technical designators. However they often mirror those.

Tag names are B<not> unique in any way. Each tag can have zero or more tag names.

The following guidelines should be followed for tag names:

=over

=item *

Tag names are for reading by a person, not a computer.
They should be useful to the user.
Including any meaning for machines should be avoided. Other relations should be used for that.

=item *

If a subject has a proper name, that name should be included as tag name as-is.
For examples Richard George Adams' tag should include the tag name C<Richard George Adams>.
However if there are valid variations they should also be included.
Such as C<Richard Adams> as his middle name is commonly not used in his publications.

B<Note:>
Tag names can contain any character. It is therefore possible to include non-latin scripts.
Spaces are valid.

B<Note:>
If a proper name is commonly translated (such as city names) more languages might be included.
See below.

=item *

If the subject does not have a proper name it is common to use the English (that is British)
name. If the subject is specific to a social context (such as a city that is located within some nation)
than it is common to include the name of the subject that is native to that context.

It is possible to include names in more languages if needed.

It is also possible to use I<context> in the link denoting the name to provide cultural, language, or other
context for the name.

=item *

Subjects without a proper name and (often) I<abstract> subjects may sometimes require more than one word to
build a useful tag name.
While spaces are valid in tag names it is often harder to enter them in computer systems.
For example lists of keywords are often separating individual keywords by space.
In that case the use of dash (C<->) is native. Underscore (C<_>) or CamelCase or similar is dissuaded.

=item *

Tag names must not include any non-name part (such symbols of sex, membership of a social context or movement).
there are other relations for this.

=item *

Tag names for relations that allow or encourage multiple values are commonly prefixed with C<also->.
For example C<also-has-role> and C<also-shares-identifier>.

Tag names for subjects that are super types of other subjects are commonly prefixed with C<proto->.
Examples include C<proto-file> and C<proto-entity>.

See also L<Data::TagDB::Tutorial::WellKnown> for more examples.

=back

=head1 Types and roles

Each subject has zero or one type and zero or more roles. The type of a subject is one of it's roles.

Each role defines a set of properties or operations that can be done with the subject.
For example one might own an apple (I<specific>) that has the type of apples (I<abstract>) that has also
the role of a fruit.

In software development this is often implemented as types and inherence.
See for example L<perlfunc/package>, L<UNIVERSAL/ise>, and L<UNIVERSAL/DOES> for Perl's implementation.

B<Note:>
It is often not clear when creating a tag what it's type actually is. In this case it is wise
to not set the type at all but set those roles that it implements.

B<Note:>
While each subject has only one type, in a real world database a tag might have several C<has-type> relations.
However this is only allowed if those types are actually in inherence. As the data might not be complete this
might be hard to check.
Therefore, it might be wide to allow multiple C<has-type> alike C<also-has-role> however print a warning.

See also
L<Data::TagDB::Tutorial::WellKnown/also-has-role>,
L<Data::TagDB::Tutorial::WellKnown/has-type>.

=head2 Type inherence

To implement inherence in types the relations C<specialises> and C<generalises> are used.

It is very common to have multi level type trees.
For newly defined types it is also wise to specialise them from common well known types.
This allows software that is not aware of them to perform basic operations
(such as to correctly display them to the user).

See also
L<Data::TagDB::Tutorial::WellKnown/specialises>,
L<Data::TagDB::Tutorial::WellKnown/generalises>.

=head2 Common types

The following types are very common. Many other complex types specialise them.

See also
L<Data::TagDB::Tutorial::WellKnown>.

=head3 Types and roles

Types and roles inherit from C<subject-type>.

See also
L<Data::TagDB::Tutorial::WellKnown/subject-type>.

=head3 Entities, Persons, accounts

All accounts (like e-mail, bank, or user accounts) should have roles including
C<account> (C<b72508ba-7fb9-42ae-b4cf-b850b53a16c2>).
Accounts are owned by one or more entities.
They commonly include some amount of profile data
(such as names and contact information) and may represent the entity they are owned by.

In contrast an entity (natural or legal) should have roles including
C<entity> (C<09ade47e-b049-436b-bf10-8357f4b6bc05>).
Entities also include some amount of profile data. However this should be limited
to such data that is directly linked to the entity and is valid indefinitely
(e.g. names, cultural background, locations, and important events).
An entity never contain any technical data such as login credentials.
Such data is a clear sign that it is in fact an account.

Legal entities are entities that are created by legal means. Most commonly
companies. In order for them to be legal entities registration and legal
documentation is needed.
Such entities should include the role C<legal-entity> (C<f57f5e00-1d08-4731-b49b-c8316e23f06a>).
If it is unclear if a group qualifies as a legal entity (e.g. people doing something together vs.
a registered association) it is wise to only mark it as C<entity>.

Natural entities are I<living beings>.
Those include alive, dead, real, fictional, human and non-human beings.
Such subjects should have the role
C<natural-entity> AKA C<person> (C<f6249973-59a9-47e2-8314-f7cf9a5f77bf>) included in their list of roles.

In addition to the C<natural-entity> the universal tag model includes the type
C<body> (C<5501e545-f39a-4d62-9f65-792af6b0ccba>) used to record all what is related to the body of a person,
such as birthday, locations, and species.
And C<character> (C<a331f2c5-20e5-4aa2-b277-8e63fd03438d>) used to record anything about the character of a person,
such as identity, world view, and interests.

B<Note:>
When in doubt it is wise to use the role
C<proto-entity> (C<7be4d8c7-6a75-44cc-94f7-c87433307b26>).
It is the super-role for all other entity and account roles and provides many common properties.

=head3 Files

There are four different things people commonly refer to as files:
I<hardlinks>, I<inodes>, I<bit exact copies>, and I<creative works>.

We'll conver each in their own section. Here is a basic overview to find out
what section is the correct one:

=over

=item I<Hardlinks>

If you consider two files the same if they have the same filename
(that is on the same machine and the B<full> path matches) even if the content,
timestamps, and file attributes change you most likely mean I<hardlinks>.

=item I<Inodes>

If you consider two files the same if refer to the same physical storage (the same blocks on the disk),
indepdenent on the filename (and path), and permit for the content, timestamps, and file attributes to
change but consider each copy (that does not share blocks and therefore can change indepndently) distict
(this also implies that any copy on a different disk is a distinct) you likely mean I<inodes>.

=item I<Bit exact copies>

If you consider any copy that has exactly (bit-wise) the same content, independent on it's storage the same
then you most likely mean I<bit exact copies> (sometimes also called I<states>).

This also implies that if two files have the same hash or checksum they are likely the same, but if they have
different hashes or checksums they are always distinct.

=item I<Creative works>

If you consider all copies the same that have the same human readable content, independent on storage location
and file format, encoding, or any other property you likely mean a I<creative work>.

B<Note:>
While creative works are one of the fundamental types they are strictly speaking not files by the definition of
a file. Therefore they are covered in their own section under L</Creative works>.

=back

=head4 Hardlinks

Hardlinks are very volatile as they often change over time. Therefore it is hard to include them in a non-volatile
data model. It is best to consider if the data one wants to store is better bound to another propery than the filename
(alone).

If hardlinks are however used, they have the type/role C<hardlink> (C<61fba55f-1ba3-460d-85a7-9262557f41c9>.
It also seems wise to include the basename (that is the filename without drive and directory) as a
L<tagname|Data::TagDB::Tutorial::WellKnown/tagname>.
A C<also-on-filesystem> (C<cd5bfb11-620b-4cce-92bd-85b7d010f070>) relation also seems to be helpful to locate the device.
A L<also-list-contains-also|Data::TagDB::Tutorial::WellKnown/also-list-contains-also> may be used
on the directory the link is part of.

=head4 Inodes

Inodes are a fundamental filesystem object. Flat files, directories, symlinks, and other data is stored
as an inode on the filesystem. Hardlinks give names to inodes. There can be any number (even zero) of hardlinks
to an inode.
An inode is known by it's inode-number to the filesystem. For any point time knowing the filesystem a file is on
and it's inode number uniquely identifies the file. However once a file is deleted the inode number may be reused
by the filesystem.

Therefore for software that depends on the use of inode numbers as keys they must ensure the inode is not deleted.
At runtime this can be achieved by keeping an handle to the file open. Between runtimes this is harder.
If the inode can be set to immutable that is often the best option. However that may require support by the system
and corresponding rights.
Having a shadow hardlink or setting the file to read only may or may not provide similar semantics depending on the
usecase, operating system, and filesystem.

The type/role to be used with inodes is C<inode> (C<59a5691a-6a19-4051-bc26-8db82c019df3>.
They should include a relation C<also-on-filesystem> (C<cd5bfb11-620b-4cce-92bd-85b7d010f070>), and
C<inode-number> (C<d2526d8b-25fa-4584-806b-67277c01c0db>).

It is recommended that they include C<final-*> relations, such as
L<final-file-hash|Data::TagDB::Tutorial::WellKnown/final-file-hash>, or
C<has-final-state> (C<54d30193-2000-4d8a-8c28-3fa5af4cad6b>).

Any intermediate state may be recorded using C<also-has-state> (C<4c426c3c-900e-4350-8443-e2149869fbc9>).

=head4 Bit exact copies

Bit exact copies are the way to look at files that will not change, or files that will transit between well defined states.
This is the case for example for documents that need to be archived, static assets, files under version or revision control
(such as files in git), disk images, most types of publications and many more.
It is one of the preferred ways to look at files. However it is often combined with one of the other types.
For example one might expect a never changing document under a given filename (I<hardlink> plus I<bit exact copy>).

Tags for bit exact copies include the role L<proto-file|Data::TagDB::Tutorial::WellKnown/proto-file>. They are also often
used as the I<related> (target) of a I<has-final-state> or I<also-has-state> relation. In that case they are also known
as a I<state> the file can be in.

Such tags commonly also contain a number of C<final-*> relations.
Very common are
L<final-file-hash|Data::TagDB::Tutorial::WellKnown/final-file-hash>,
L<final-file-size|Data::TagDB::Tutorial::WellKnown/final-file-size>, and
L<final-file-encoding|Data::TagDB::Tutorial::WellKnown/final-file-encoding>.

=head3 Creative works

A creative work is any work that was created by an author.
Common types include texts, pictures, songs, videos, theatre plays, and curated collections.

Each of those types has it's very own set of roles and relations that are specific to the type.
However all of them should have the role C<creative-work> (C<84402088-2d3b-49c2-af16-f7715b54f051>).

Common relations for all/most kinds of work include
C<also-has-artist> (C<94a4ce85-dda0-433e-8b57-949a20606d7f>),
C<also-has-topic>  (C<38314410-0eeb-442f-8215-fcded3d35738>),
C<also-has-title>  (C<f7fd59e6-6727-4128-a0a7-cbc702dc09b8>), and
C<also-depicts>    (C<a6ff7196-bc1a-4bee-9ee4-de99767cf236>).

=head1 AUTHOR

Philipp Schafft <lion@cpan.org>

=head1 COPYRIGHT AND LICENSE

This software is Copyright (c) 2024-2025 by Philipp Schafft <lion@cpan.org>.

This is free software, licensed under:

  The Artistic License 2.0 (GPL Compatible)

=cut
