<!DOCTYPE article SYSTEM "supybot.dtd">

<article>
    <articleinfo>
	    <authorgroup>
		    <author>
			    <firstname>Jeremiah</firstname>
				<surname>Fincher</surname>
	        </author>
			<editor>
				<firstname>Daniel</firstname>
				<surname>DiPaolo</surname>
				<contrib>DocBook translator</contrib>
			</editor>
		</authorgroup>
		<title>Supybot capabilities system explanation</title>
		<revhistory>
			<revision>
				<revnumber>0.1</revnumber>
				<date>18 Feb 2004</date>
				<revremark>Initial Docbook translation</revremark>
			</revision>
			<revision>
				<revnumber>0.2</revnumber>
				<date>04 Sep 2004</date>
				<revremark>Update Docbook translation</revremark>
			</revision>
		</revhistory>
	</articleinfo>
	<sect1>
	    <title>Introduction</title>
		<subtitle>
			Supybot's capabilities overview and comparisons to other bots
	    </subtitle>
		<para>
			Ok, some some explanation of the capabilities system is probably
			in order.  With most IRC bots (including the ones I've written
			myself prior to this one) &ldquo;what a user can do&rdquo; is set
			in one of two ways.  On the <emphasis>really</emphasis> simple
			bots, each user has a numeric &ldquo;level&rdquo; and commands
			check to see if a user has a &ldquo;high enough level&rdquo; to
			perform some operation.  On bots that are slightly more
			complicated, users have a list of &ldquo;flags&rdquo; whose
			meanings are hardcoded, and the bot checks to see if a user
			possesses the necessary flag before performing some operation.
			Both methods, IMO, are rather arbitrary, and force the user and
			the programmer to be unduly confined to less expressive
			constructs.
		</para>
		<para>
			This bot is different.  Every user has a set of
			&ldquo;capabilities&rdquo; that is consulted every time they give
			the bot a command.  Commands, rather than checking for a user
			level of 100, or checking if the user has an <varname>o</varname>
			flag, are instead able to check if a user has the
			<capability>owner</capability> capability.  At this point such a
			difference might not seem revolutionary, but at least we can
			already tell that this method is self-documenting, and easier for
			users and developers to understand what's truly going on.  
		</para>
	</sect1>
	<sect1>
		<title>What sets supybot's capabilities apart</title>
		<para>
			If that was all, well, the capability system would be
			&ldquo;cool&rdquo;, but not many people would say it was
			&ldquo;awesome&rdquo;.  But it <emphasis>is</emphasis> awesome!
			Several things are happening behind the scene that make it
			awesome, and these are things that couldn't happen if the bot was
			using numeric userlevels or single-character flags.  First,
			whenever a user issues the bot a command, the command dispatcher
			checks to make sure the user doesn't have the
			&ldquo;anticapability&rdquo; for that command.  An anticapability is
			a capability that, instead of saying &ldquo;what a user can
			do&rdquo;, says what a user <emphasis>cannot</emphasis> do.  It's
			formed rather simply by adding a dash (&ldquo;-&rdquo;) to the
			beginning of a capability; <botcommand>rot13</botcommand> is a
			capability, and <botcommand>-rot13</botcommand> is an
			anticapability.  Anyway, when a user issues the bot a command,
			perhaps <botcommand>calc</botcommand> or
			<botcommand>help</botcommand>, the bot first checks to make sure
			the user doesn't have the <capability>-calc</capability> or the
			<capability>-help</capability> capabilities before even
			considering responding to the user.  So commands can be turned on
			or off on a <emphasis>per user</emphasis> basis, offering
			finegrained control not often (if at all!) seen in other bots.
		</para>
		<sect2>
			<title>Channel capabilities</title>
			<para>
				But that's not all!  The capabilities system also supports
				<emphasis>Channel</emphasis> capabilities, which are
				capabilities that only apply to a specific channel; they're of
				the form <capability>#channel,capability</capability>.
				Whenever a user issues a command to the bot in a channel, the
				command dispatcher also checks to make sure the user doesn't
				have the anticapability for that command <emphasis>in that
				channel</emphasis> and if the user does, the bot won't respond
				to the user in the channel.  Thus now, in addition to having
				the ability to turn individual commands on or off for an
				individual user, we can now turn commands on or off for an
				individual user on an individual channel!
			</para>
			<para>
				So when a user <nick>foo</nick> sends a command
				<botcommand>bar</botcommand> to the bot on channel
				<channel>#baz</channel>, first the bot checks to see if the
				user has the anticapability for the command by itself,
				<capability>-bar</capability>.  If so, it returns right then
				and there, compltely ignoring the fact that the user issued
				that command to it.  If the user doesn't have that
				anticapability, then the bot checks to see if the user issued
				the command over a channel, and if so, checks to see if the
				user has the antichannelcapability for that command,
				<capability>#baz,-bar</capability>.  If so, again, he returns
				right then and there and doesn't even think about responding
				to the bot.  If neither of these anticapabilities are present,
				then the bot just responds to the user like normal.
			</para>
		</sect2>
	</sect1>
	<sect1>
		<title>Motivations behind the capabilities system</title>
		<sect2>
			<title>A programmer's perspective</title>
			<para>
				From a programming perspective, capabilties are easy to use
				and flexible.  Any command can check if a user has any
				capability, even ones not thought of when the bot was
				originally written.  Commands/Callbacks can add their own
				capabilities &ndash; it's as easy as just checking for a
				capability and documenting somewhere that a user needs that
				capability to do something.
			</para>
		</sect2>
		<sect2>
			<title>An end-user's perspective</title>
			<para>
				From an end-user perspective, capabilities remove a lot of the
				mystery and esotery of bot control, in addition to giving the
				user absolutely finegrained control over what users are
				allowed to do with the bot.  Additionally, defaults can be set
				by the end-user for both individual channels and for the bot
				as a whole, letting an end-user set the policy he wants the
				bot to follow for users that haven't yet registered in his
				user database.
			</para>
		</sect2>
		<para>
			It's really a revolution!
		</para>
	</sect1>
	<sect1>
		<title>Hard-coded supybot capabilities</title>
		<para>
			There are several default capabilities the bot uses.  The most
			important of these is the <capability>owner</capability>
			capability.  This capability allows the person having it to use
			<emphasis>any</emphasis> command.  It's best to keep this
			capability reserved to people who actually have access to the
			shell the bot is running on.  
		</para>
		<para>
			There is also the <capability>admin</capability> capability for
			non-owners that are highly trusted to administer the bot
			appropriately.  They can do things such as change the bot's nick,
			globally enable/disable commands, cause the bot to ignore a given
			user, set the prefixchar, report bugs, etc.  They generally cannot
			do administration related to channels, which is reserved for
			people with the next capability.
		</para>
		<para>
			People who are to administer channels with the bot should have the
			<capability>#channel,op</capability> capability &ndash; whatever
			channel they are to administrate, they should have that channel
			capability for <capability>op</capability>.  For example, since I
			want <nick>inkedmn</nick> to be an administrator in
			<channel>#supybot</channel>, I'll give him the
			<capability>#supybot,op</capability> capability.  This is in
			addition to his <capability>admin</capability> capability, since
			the <capability>admin</capability> capability doesn't give the
			person having it control over channels.
			<capability>#channel.op</capability> is used for such things as
			giving/receiving ops, kickbanning people, lobotomizing the bot,
			ignoring users in the channel, and managing the channel
			capabilities.  The <capability>#channel,op</capability> capability
			is also basically the equivalent of the owner capability for
			capabilities involving <channel>#channel</channel> &ndash;
			basically anyone with the <capability>#channel,op</capability>
			capability is considered to have all positive capabilities and no
			negative capabilities for <channel>#channel</channel>.
		</para>
		<para>
			One other globally important capability exists:
			<capability>trusted</capability>.  This is a command that
			basically says &ldquo;This user can be trusted not to try and
			crash the bot.&rdquo; It allows users to call commands like
			<botcommand>Math.icalc</botcommand>, which potentially could cause the
			bot to begin a calculation that could potentially never return (a
			calculation like 10**10**10**10).  Another command that requires
			the trusted capability is <botcommand>Utilties.re</botcommand>, which
			(due to the regular expression implementation in Python (and any
			other language that uses NFA regular expressions, like Perl or
			Ruby or Lua or &hellip;) which can allow a regular expression to
			take exponential time to process).  Consider what would happen if
			the someone gave the bot the command <literal>re [strjoin "" s/./
			[dict go] /] [dict go]</literal>.
		</para>
	</sect1>
	<sect1>
		<title>Other capabilities</title>
		<para>
			Other plugins may require different capabilities; the
            <plugin>Factoids</plugin> plugin requires
            <capability>#channel,factoids</capability>, the <plugin>Topic</plugin>
            plugin requires <capability>#channel,topic</capability>, etc.
		</para>
	</sect1>
</article>