commit 95c614fb95453ba55991544a66f57316ce786cb1 Author: Maxwell Friedman Date: Thu Sep 24 09:52:57 2026 -0400 Add files via upload diff --git a/IEEEtran.bst b/IEEEtran.bst new file mode 100644 index 0000000..b9c3b93 --- /dev/null +++ b/IEEEtran.bst @@ -0,0 +1,2365 @@ +%% +%% IEEEtran.bst +%% BibTeX Bibliography Style file for IEEE Journals and Conferences (unsorted) +%% Version 1.10 (2002/09/27) +%% +%% Copyright (c) 2002 Michael Shell +%% +%% Original starting code base and algorithms obtained from the output of +%% Patrick W. Daly's makebst package as well as from prior versions of +%% IEEE BibTeX styles: +%% +%% 1. Howard Trickey and Oren Patashnik's ieeetr.bst (1985/1988) +%% 2. Silvano Balemi and Richard H. Roy's IEEEbib.bst (1993) +%% +%% +%% See: +%% http://www.ctan.org/tex-archive/macros/latex/contrib/supported/IEEEtran/ +%% for latest version and current contact information. +%% +%% For use with BibTeX version 0.99a or later +%% +%% This is a numerical citation style. +%% +%%********************************************************************** +%% Legal Notice: +%% This code is offered as-is without any warranty either expressed or +%% implied; without even the implied warranty of MERCHANTABILITY or +%% FITNESS FOR A PARTICULAR PURPOSE! +%% User assumes all risk. +%% In no event shall IEEE or any contributor to this code be liable for +%% any damages or losses, including, but not limited to, incidental, +%% consequential, or any other damages, resulting from the use or misuse +%% of any information contained here. +%% +%% This code is distributed under the Perl Artistic License +%% ( http://language.perl.com/misc/Artistic.html ) +%% and may be freely used, distributed and modified - subject to the +%% constraints therein. +%% Retain all contribution notices, credits and disclaimers. +%% +%% All comments are the opinions of their respective authors and are not +%% necessarily endorsed by the IEEE. +%%********************************************************************** +% +% +% Changelog: +% +% 1.00 (2002/08/13) Initial release +% +% 1.10 (2002/09/27) +% 1. Corrected minor bug for improperly formed warning message when a +% book was not given a title. Thanks to Ming Kin Lai for reporting this. +% 2. Added support for CTLname_format_string and CTLname_latex_cmd fields +% in the BST control entry type. + + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% DEFAULTS FOR THE CONTROLS OF THE BST STYLE %% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% These are the defaults for the user adjustable controls. The values used +% here can be overridden by the user via IEEEtranBSTCTL entry type. + +% NOTE: The recommended LaTeX command to invoke a control entry type is: +% +%\makeatletter +%\def\bstctlcite#1{\@bsphack +% \@for\@citeb:=#1\do{% +% \edef\@citeb{\expandafter\@firstofone\@citeb}% +% \if@filesw\immediate\write\@auxout{\string\citation{\@citeb}}\fi}% +% \@esphack} +%\makeatother +% +% It is called at the start of the document, before the first \cite, like: +% \bstctlcite{IEEEexample:BSTcontrol} +% +% IEEEtran.cls V1.6 and later does provide this command. + + + +% #0 turns off the display of the number for articles. +% #1 enables +FUNCTION {default.is.use.number.for.article} { #1 } + + +% #0 turns off the display of the paper and type fields in @inproceedings. +% #1 enables +FUNCTION {default.is.use.paper} { #1 } + + +% #0 turns off the forced use of "et al." +% #1 enables +FUNCTION {default.is.forced.et.al} { #0 } + +% The maximum number of names that can be present beyond which an "et al." +% usage is forced. Be sure that num.names.shown.with.forced.et.al (below) +% is not greater than this value! +% Note: There are many instances of references in IEEE journals which have +% a very large number of authors as well as instances in which "et al." is +% used profusely. +FUNCTION {default.max.num.names.before.forced.et.al} { #10 } + +% The number of names that will be shown with a forced "et al.". +% Must be less than or equal to max.num.names.before.forced.et.al +FUNCTION {default.num.names.shown.with.forced.et.al} { #1 } + + +% #0 turns off the alternate interword spacing for entries with URLs. +% #1 enables +FUNCTION {default.is.use.alt.interword.spacing} { #1 } + +% If alternate interword spacing for entries with URLs is enabled, this is +% the interword spacing stretch factor that will be used. For example, the +% default "4" here means that the interword spacing in entries with URLs can +% stretch to four times normal. Does not have to be an integer. Note that +% the value specified here can be overridden by the user in their LaTeX +% code via a command such as: +% "\providecommand\BIBentryALTinterwordstretchfactor{1.5}" in addition to +% that via the IEEEtranBSTCTL entry type. +FUNCTION {default.ALTinterwordstretchfactor} { "4" } + + +% #0 turns off the "dashification" of repeated (i.e., identical to those +% of the previous entry) names. IEEE normally does this. +% #1 enables +FUNCTION {default.is.dash.repeated.names} { #1 } + + +% The default name format control string. +FUNCTION {default.name.format.string}{ "{f.~}{vv~}{ll}{, jj}" } + + +% The default LaTeX font command for the names. +FUNCTION {default.name.latex.cmd}{ "" } + + +% Other controls that cannot be accessed via IEEEtranBSTCTL entry type. + +% #0 turns off the terminal startup banner/completed message so as to +% operate more quietly. +% #1 enables +FUNCTION {is.print.banners.to.terminal} { #1 } + + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% FILE VERSION AND BANNER %% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +FUNCTION{bst.file.version} { "1.10" } +FUNCTION{bst.file.date} { "2002/09/27" } +FUNCTION{bst.file.website} { "http://www.ctan.org/tex-archive/macros/latex/contrib/supported/IEEEtran/" } + +FUNCTION {banner.message} +{ is.print.banners.to.terminal + { "-- IEEEtran.bst version" " " * bst.file.version * + " (" * bst.file.date * ") " * "by Michael Shell." * + top$ + "-- " bst.file.website * + top$ + "-- See the " quote$ * "IEEEtran_bst_HOWTO.pdf" * quote$ * " manual for usage information." * + top$ + } + { skip$ } + if$ +} + +FUNCTION {completed.message} +{ is.print.banners.to.terminal + { "" + top$ + "Done." + top$ + } + { skip$ } + if$ +} + + + + +%%%%%%%%%%%%%%%%%%%%%% +%% STRING CONSTANTS %% +%%%%%%%%%%%%%%%%%%%%%% + +FUNCTION {bbl.and}{ "and" } +FUNCTION {bbl.etal}{ "et~al." } +FUNCTION {bbl.editors}{ "eds." } +FUNCTION {bbl.editor}{ "ed." } +FUNCTION {bbl.edition}{ "ed." } +FUNCTION {bbl.volume}{ "vol." } +FUNCTION {bbl.of}{ "of" } +FUNCTION {bbl.number}{ "no." } +FUNCTION {bbl.in}{ "in" } +FUNCTION {bbl.pages}{ "pp." } +FUNCTION {bbl.page}{ "p." } +FUNCTION {bbl.chapter}{ "ch." } +FUNCTION {bbl.paper}{ "paper" } +FUNCTION {bbl.part}{ "pt." } +FUNCTION {bbl.patent}{ "Patent" } +FUNCTION {bbl.patentUS}{ "U.S." } +FUNCTION {bbl.revision}{ "Rev." } +FUNCTION {bbl.series}{ "ser." } +FUNCTION {bbl.standard}{ "Std." } +FUNCTION {bbl.techrep}{ "Tech. Rep." } +FUNCTION {bbl.mthesis}{ "Master's thesis" } +FUNCTION {bbl.phdthesis}{ "Ph.D. dissertation" } +FUNCTION {bbl.urlprefix}{ "[Online]. Available:" } +FUNCTION {bbl.st}{ "st" } +FUNCTION {bbl.nd}{ "nd" } +FUNCTION {bbl.rd}{ "rd" } +FUNCTION {bbl.th}{ "th" } + + +% This is the LaTeX spacer that is used when a larger than normal space +% is called for (such as just before the address:publisher). +FUNCTION {large.space} { "\hskip 1em plus 0.5em minus 0.4em\relax " } + +% The LaTeX code for dashes that are used to represent repeated names. +% Note: Some older IEEE journals used something like +% "\rule{0.275in}{0.5pt}\," which is fairly thick and runs right along +% the baseline. However, IEEE now uses a thinner, above baseline, +% six dash long sequence. +FUNCTION {repeated.name.dashes} { "------" } + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% PREDEFINED STRING MACROS %% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +MACRO {jan} {"Jan."} +MACRO {feb} {"Feb."} +MACRO {mar} {"Mar."} +MACRO {apr} {"Apr."} +MACRO {may} {"May"} +MACRO {jun} {"June"} +MACRO {jul} {"July"} +MACRO {aug} {"Aug."} +MACRO {sep} {"Sept."} +MACRO {oct} {"Oct."} +MACRO {nov} {"Nov."} +MACRO {dec} {"Dec."} + + + +%%%%%%%%%%%%%%%%%% +%% ENTRY FIELDS %% +%%%%%%%%%%%%%%%%%% + +ENTRY + { address + assignee + author + booktitle + chapter + day + dayfiled + edition + editor + howpublished + institution + intype + journal + key + language + month + monthfiled + nationality + note + number + organization + pages + paper + publisher + school + series + revision + title + type + url + volume + year + yearfiled + CTLuse_article_number + CTLuse_paper + CTLuse_forced_etal + CTLmax_names_forced_etal + CTLnames_show_etal + CTLuse_alt_spacing + CTLalt_stretch_factor + CTLdash_repeated_names + CTLname_format_string + CTLname_latex_cmd + } + {} + { label } + + + + +%%%%%%%%%%%%%%%%%%%%%%% +%% INTEGER VARIABLES %% +%%%%%%%%%%%%%%%%%%%%%%% + +INTEGERS { prev.status.punct this.status.punct punct.std + punct.no punct.comma punct.period + prev.status.space this.status.space space.std + space.no space.normal space.large + prev.status.quote this.status.quote quote.std + quote.no quote.close + prev.status.nline this.status.nline nline.std + nline.no nline.newblock + status.cap cap.std + cap.no cap.yes} + +INTEGERS { longest.label.width multiresult nameptr namesleft number.label numnames } + +INTEGERS { is.use.number.for.article + is.use.paper + is.forced.et.al + max.num.names.before.forced.et.al + num.names.shown.with.forced.et.al + is.use.alt.interword.spacing + is.dash.repeated.names} + + +%%%%%%%%%%%%%%%%%%%%%% +%% STRING VARIABLES %% +%%%%%%%%%%%%%%%%%%%%%% + +STRINGS { bibinfo + longest.label + oldname + s + t + ALTinterwordstretchfactor + name.format.string + name.latex.cmd} + + + + +%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOW LEVEL FUNCTIONS %% +%%%%%%%%%%%%%%%%%%%%%%%%% + +FUNCTION {initialize.controls} +{ default.is.use.number.for.article 'is.use.number.for.article := + default.is.use.paper 'is.use.paper := + default.is.forced.et.al 'is.forced.et.al := + default.max.num.names.before.forced.et.al 'max.num.names.before.forced.et.al := + default.num.names.shown.with.forced.et.al 'num.names.shown.with.forced.et.al := + default.is.use.alt.interword.spacing 'is.use.alt.interword.spacing := + default.is.dash.repeated.names 'is.dash.repeated.names := + default.ALTinterwordstretchfactor 'ALTinterwordstretchfactor := + default.name.format.string 'name.format.string := + default.name.latex.cmd 'name.latex.cmd := +} + + +% This IEEEtran.bst features a very powerful and flexible mechanism for +% controlling the capitalization, punctuation, spacing, quotation, and +% newlines of the formatted entry fields. (Note: IEEEtran.bst does not need +% or use the newline/newblock feature, but it has been implemented for +% possible future use.) The output states of IEEEtran.bst consist of +% multiple independent attributes and, as such, can be thought of as being +% vectors, rather than the simple scalar values ("before.all", +% "mid.sentence", etc.) used in most other .bst files. +% +% The more flexible and complex design used here was motivated in part by +% IEEE's rather unusual bibliography style. For example, IEEE ends the +% previous field item with a period and large space prior to the publisher +% address; the @electronic entry types use periods as inter-item punctuation +% rather than the commas used by the other entry types; and URLs are never +% followed by periods even though they are the last item in the entry. +% Although it is possible to accommodate these features with the conventional +% output state system, the seemingly endless exceptions make for convoluted, +% unreliable and difficult to maintain code. +% +% IEEEtran.bst's output state system can be easily understood via a simple +% illustration of two most recently formatted entry fields (on the stack): +% +% CURRENT_ITEM +% "PREVIOUS_ITEM +% +% which, in this example, is to eventually appear in the bibliography as: +% +% "PREVIOUS_ITEM," CURRENT_ITEM +% +% It is the job of the output routine to take the previous item off of the +% stack (while leaving the current item at the top of the stack), apply its +% trailing punctuation (including closing quote marks) and spacing, and then +% to write the result to BibTeX's output buffer: +% +% "PREVIOUS_ITEM," +% +% Punctuation (and spacing) between items is often determined by both of the +% items rather than just the first one. The presence of quotation marks +% further complicates the situation because, in standard English, trailing +% punctuation marks are supposed to be contained within the quotes. +% +% IEEEtran.bst maintains two output state (aka "status") vectors which +% correspond to the previous and current (aka "this") items. Each vector +% consists of several independent attributes which track punctuation, +% spacing, quotation, and newlines. Capitalization status is handled by a +% separate scalar because the format routines, not the output routine, +% handle capitalization and, therefore, there is no need to maintain the +% capitalization attribute for both the "previous" and "this" items. +% +% When a format routine adds a new item, it copies the current output status +% vector to the previous output status vector and (usually) resets the +% current (this) output status vector to a "standard status" vector. Using a +% "standard status" vector in this way allows us to redefine what we mean by +% "standard status" at the start of each entry handler and reuse the same +% format routines under the various inter-item separation schemes. For +% example, the standard status vector for the @book entry type may use +% commas for item separators, while the @electronic type may use periods, +% yet both entry handlers exploit many of the exact same format routines. +% +% Because format routines have write access to the output status vector of +% the previous item, they can override the punctuation choices of the +% previous format routine! Therefore, it becomes trivial to implement rules +% such as "Always use a period and a large space before the publisher." By +% pushing the generation of the closing quote mark to the output routine, we +% avoid all the problems caused by having to close a quote before having all +% the information required to determine what the punctuation should be. +% +% The IEEEtran.bst output state system can easily be expanded if needed. +% For instance, it is easy to add a "space.tie" attribute value if the +% bibliography rules mandate that two items have to be joined with an +% unbreakable space. + +FUNCTION {initialize.status.constants} +{ #0 'punct.no := + #1 'punct.comma := + #2 'punct.period := + #0 'space.no := + #1 'space.normal := + #2 'space.large := + #0 'quote.no := + #1 'quote.close := + #0 'cap.no := + #1 'cap.yes := + #0 'nline.no := + #1 'nline.newblock := +} + +FUNCTION {std.status.using.comma} +{ punct.comma 'punct.std := + space.normal 'space.std := + quote.no 'quote.std := + nline.no 'nline.std := + cap.no 'cap.std := +} + +FUNCTION {std.status.using.period} +{ punct.period 'punct.std := + space.normal 'space.std := + quote.no 'quote.std := + nline.no 'nline.std := + cap.yes 'cap.std := +} + +FUNCTION {initialize.prev.this.status} +{ punct.no 'prev.status.punct := + space.no 'prev.status.space := + quote.no 'prev.status.quote := + nline.no 'prev.status.nline := + punct.no 'this.status.punct := + space.no 'this.status.space := + quote.no 'this.status.quote := + nline.no 'this.status.nline := + cap.yes 'status.cap := +} + +FUNCTION {this.status.std} +{ punct.std 'this.status.punct := + space.std 'this.status.space := + quote.std 'this.status.quote := + nline.std 'this.status.nline := +} + +FUNCTION {cap.status.std}{ cap.std 'status.cap := } + +FUNCTION {this.to.prev.status} +{ this.status.punct 'prev.status.punct := + this.status.space 'prev.status.space := + this.status.quote 'prev.status.quote := + this.status.nline 'prev.status.nline := +} + + +FUNCTION {not} +{ { #0 } + { #1 } + if$ +} + +FUNCTION {and} +{ { skip$ } + { pop$ #0 } + if$ +} + +FUNCTION {or} +{ { pop$ #1 } + { skip$ } + if$ +} + + +% convert the strings "yes" or "no" to #1 or #0 respectively +FUNCTION {yes.no.to.int} +{ "l" change.case$ duplicate$ + "yes" = + { pop$ #1 } + { duplicate$ "no" = + { pop$ #0 } + { "unknown boolean " quote$ * swap$ * quote$ * + " in " * cite$ * warning$ + #0 + } + if$ + } + if$ +} + + +% pushes true if the single char string on the stack is in the +% range of "0" to "9" +FUNCTION {is.num} +{ chr.to.int$ + duplicate$ "0" chr.to.int$ < not + swap$ "9" chr.to.int$ > not and +} + +% multiplies the integer on the stack by a factor of 10 +FUNCTION {bump.int.mag} +{ #0 'multiresult := + { duplicate$ #0 > } + { #1 - + multiresult #10 + + 'multiresult := + } + while$ +pop$ +multiresult +} + +% converts a single character string on the stack to an integer +FUNCTION {char.to.integer} +{ duplicate$ + is.num + { chr.to.int$ "0" chr.to.int$ - } + {"noninteger character " quote$ * swap$ * quote$ * + " in integer field of " * cite$ * warning$ + #0 + } + if$ +} + +% converts a string on the stack to an integer +FUNCTION {string.to.integer} +{ duplicate$ text.length$ 'namesleft := + #1 'nameptr := + #0 'numnames := + { nameptr namesleft > not } + { duplicate$ nameptr #1 substring$ + char.to.integer numnames bump.int.mag + + 'numnames := + nameptr #1 + + 'nameptr := + } + while$ +pop$ +numnames +} + + + + +% The output routines write out the *next* to the top (previous) item on the +% stack, adding punctuation and such as needed. Since IEEEtran.bst maintains +% the output status for the top two items on the stack, these output +% routines have to consider the previous output status (which corresponds to +% the item that is being output). Full independent control of punctuation, +% closing quote marks, spacing, and newblock is provided. +% +% "output.nonnull" does not check for the presence of a previous empty +% item. +% +% "output" does check for the presence of a previous empty item and will +% remove an empty item rather than outputing it. +% +% "output.warn" is like "output", but will issue a warning if it detects +% an empty item. + +FUNCTION {output.nonnull} +{ swap$ + prev.status.punct punct.comma = + { "," * } + { skip$ } + if$ + prev.status.punct punct.period = + { add.period$ } + { skip$ } + if$ + prev.status.quote quote.close = + { "''" * } + { skip$ } + if$ + prev.status.space space.normal = + { " " * } + { skip$ } + if$ + prev.status.space space.large = + { large.space * } + { skip$ } + if$ + write$ + prev.status.nline nline.newblock = + { newline$ "\newblock " write$ } + { skip$ } + if$ +} + +FUNCTION {output} +{ duplicate$ empty$ + 'pop$ + 'output.nonnull + if$ +} + +FUNCTION {output.warn} +{ 't := + duplicate$ empty$ + { pop$ "empty " t * " in " * cite$ * warning$ } + 'output.nonnull + if$ +} + +% "fin.entry" is the output routine that handles the last item of the entry +% (which will be on the top of the stack when "fin.entry" is called). + +FUNCTION {fin.entry} +{ this.status.punct punct.no = + { skip$ } + { add.period$ } + if$ + this.status.quote quote.close = + { "''" * } + { skip$ } + if$ +write$ +newline$ +} + + +FUNCTION {is.last.char.not.punct} +{ duplicate$ + "}" * add.period$ + #-1 #1 substring$ "." = +} + +FUNCTION {is.multiple.pages} +{ 't := + #0 'multiresult := + { multiresult not + t empty$ not + and + } + { t #1 #1 substring$ + duplicate$ "-" = + swap$ duplicate$ "," = + swap$ "+" = + or or + { #1 'multiresult := } + { t #2 global.max$ substring$ 't := } + if$ + } + while$ + multiresult +} + +FUNCTION {capitalize}{ "u" change.case$ "t" change.case$ } + +FUNCTION {emphasize} +{ duplicate$ empty$ + { pop$ "" } + { "\emph{" swap$ * "}" * } + if$ +} + +FUNCTION {do.name.latex.cmd} +{ name.latex.cmd + empty$ + { skip$ } + { name.latex.cmd "{" * swap$ * "}" * } + if$ +} + +% IEEEtran.bst uses its own \BIBforeignlanguage command which directly +% invokes the TeX hyphenation patterns without the need of the Babel +% package. Babel does a lot more than switch hyphenation patterns and +% its loading can cause unintended effects in many class files (such as +% IEEEtran.cls). +FUNCTION {select.language} +{ duplicate$ empty$ 'pop$ + { language empty$ 'skip$ + { "\BIBforeignlanguage{" language * "}{" * swap$ * "}" * } + if$ + } + if$ +} + +FUNCTION {tie.or.space.prefix} +{ duplicate$ text.length$ #3 < + { "~" } + { " " } + if$ + swap$ +} + +FUNCTION {get.bbl.editor} +{ editor num.names$ #1 > 'bbl.editors 'bbl.editor if$ } + +FUNCTION {space.word}{ " " swap$ * " " * } + + +% Field Conditioners, Converters, Checkers and External Interfaces + +FUNCTION {empty.field.to.null.string} +{ duplicate$ empty$ + { pop$ "" } + { skip$ } + if$ +} + +FUNCTION {either.or.check} +{ empty$ + { pop$ } + { "can't use both " swap$ * " fields in " * cite$ * warning$ } + if$ +} + +FUNCTION {empty.entry.warn} +{ author empty$ title empty$ howpublished empty$ + month empty$ year empty$ note empty$ url empty$ + and and and and and and + { "all relevant fields are empty in " cite$ * warning$ } + 'skip$ + if$ +} + + +% The bibinfo system provides a way for the electronic parsing/acquisition +% of a bibliography's contents as is done by ReVTeX. For example, a field +% could be entered into the bibliography as: +% \bibinfo{volume}{2} +% Only the "2" would show up in the document, but the LaTeX \bibinfo command +% could do additional things with the information. IEEEtran.bst does provide +% a \bibinfo command via "\providecommand{\bibinfo}[2]{#2}". However, it is +% currently not used as the bogus bibinfo functions defined here output the +% entry values directly without the \bibinfo wrapper. The bibinfo functions +% themselves (and the calls to them) are retained for possible future use. +% +% bibinfo.check avoids acting on missing fields while bibinfo.warn will +% issue a warning message if a missing field is detected. Prior to calling +% the bibinfo functions, the user should push the field value and then its +% name string, in that order. + +FUNCTION {bibinfo.check} +{ swap$ duplicate$ missing$ + { pop$ pop$ "" } + { duplicate$ empty$ + { swap$ pop$ } + { swap$ pop$ } + if$ + } + if$ +} + +FUNCTION {bibinfo.warn} +{ swap$ duplicate$ missing$ + { swap$ "missing " swap$ * " in " * cite$ * warning$ pop$ "" } + { duplicate$ empty$ + { swap$ "empty " swap$ * " in " * cite$ * warning$ } + { swap$ pop$ } + if$ + } + if$ +} + + +% IEEE separates large numbers with more than 4 digits into groups of +% three. IEEE uses a small space to separate these number groups. +% Typical applications include patent and page numbers. + +% number of consecutive digits required to trigger the group separation. +FUNCTION {large.number.trigger}{ #5 } + +% For numbers longer than the trigger, this is the blocksize of the groups. +% The blocksize must be less than the trigger threshold, and 2 * blocksize +% must be greater than the trigger threshold (can't do more than one +% separation on the initial trigger). +FUNCTION {large.number.blocksize}{ #3 } + +% What is actually inserted between the number groups. +FUNCTION {large.number.separator}{ "\," } + +% So as to save on integer variables by reusing existing ones, numnames +% holds the current number of consecutive digits read and nameptr holds +% the number that will trigger an inserted space. +FUNCTION {large.number.separate} +{ 't := + "" + #0 'numnames := + large.number.trigger 'nameptr := + { t empty$ not } + { t #-1 #1 substring$ is.num + { numnames #1 + 'numnames := } + { #0 'numnames := + large.number.trigger 'nameptr := + } + if$ + t #-1 #1 substring$ swap$ * + t #-2 global.max$ substring$ 't := + numnames nameptr = + { duplicate$ #1 nameptr large.number.blocksize - substring$ swap$ + nameptr large.number.blocksize - #1 + global.max$ substring$ + large.number.separator swap$ * * + nameptr large.number.blocksize - 'numnames := + large.number.blocksize #1 + 'nameptr := + } + { skip$ } + if$ + } + while$ +} + +% Converts all single dashes "-" to double dashes "--". +FUNCTION {n.dashify} +{ large.number.separate + 't := + "" + { t empty$ not } + { t #1 #1 substring$ "-" = + { t #1 #2 substring$ "--" = not + { "--" * + t #2 global.max$ substring$ 't := + } + { { t #1 #1 substring$ "-" = } + { "-" * + t #2 global.max$ substring$ 't := + } + while$ + } + if$ + } + { t #1 #1 substring$ * + t #2 global.max$ substring$ 't := + } + if$ + } + while$ +} + + +% This function detects entries with names that are identical to that of +% the previous entry and replaces the repeated names with dashes (if the +% "is.dash.repeated.names" user control is nonzero). +FUNCTION {name.or.dash} +{ 's := + oldname empty$ + { s 'oldname := s } + { s oldname = + { is.dash.repeated.names + { repeated.name.dashes } + { s 'oldname := s } + if$ + } + { s 'oldname := s } + if$ + } + if$ +} + +% Converts the number string on the top of the stack to +% "numerical ordinal form" (e.g., "7" to "7th"). There is +% no artificial limit to the upper bound of the numbers as the +% least significant digit always determines the ordinal form. +FUNCTION {num.to.ordinal} +{ duplicate$ #-1 #1 substring$ "1" = + { bbl.st * } + { duplicate$ #-1 #1 substring$ "2" = + { bbl.nd * } + { duplicate$ #-1 #1 substring$ "3" = + { bbl.rd * } + { bbl.th * } + if$ + } + if$ + } + if$ +} + +% If the string on the top of the stack begins with a number, +% (e.g., 11th) then replace the string with the leading number +% it contains. Otherwise retain the string as-is. s holds the +% extracted number, t holds the part of the string that remains +% to be scanned. +FUNCTION {extract.num} +{ duplicate$ 't := + "" 's := + { t empty$ not } + { t #1 #1 substring$ + t #2 global.max$ substring$ 't := + duplicate$ is.num + { s swap$ * 's := } + { pop$ "" 't := } + if$ + } + while$ + s empty$ + 'skip$ + { pop$ s } + if$ +} + +% Converts the word number string on the top of the stack to +% Arabic string form. Will be successful up to "tenth". +FUNCTION {word.to.num} +{ duplicate$ "l" change.case$ 's := + s "first" = + { pop$ "1" } + { skip$ } + if$ + s "second" = + { pop$ "2" } + { skip$ } + if$ + s "third" = + { pop$ "3" } + { skip$ } + if$ + s "fourth" = + { pop$ "4" } + { skip$ } + if$ + s "fifth" = + { pop$ "5" } + { skip$ } + if$ + s "sixth" = + { pop$ "6" } + { skip$ } + if$ + s "seventh" = + { pop$ "7" } + { skip$ } + if$ + s "eighth" = + { pop$ "8" } + { skip$ } + if$ + s "ninth" = + { pop$ "9" } + { skip$ } + if$ + s "tenth" = + { pop$ "10" } + { skip$ } + if$ +} + + +% Converts the string on the top of the stack to numerical +% ordinal (e.g., "11th") form. +FUNCTION {convert.edition} +{ duplicate$ empty$ 'skip$ + { duplicate$ #1 #1 substring$ is.num + { extract.num + num.to.ordinal + } + { word.to.num + duplicate$ #1 #1 substring$ is.num + { num.to.ordinal } + { "edition ordinal word " quote$ * edition * quote$ * + " may be too high (or improper) for conversion" * " in " * cite$ * warning$ + } + if$ + } + if$ + } + if$ +} + + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LATEX BIBLIOGRAPHY CODE %% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +FUNCTION {start.entry} +{ newline$ + "\bibitem{" write$ + cite$ write$ + "}" write$ + newline$ + "" + initialize.prev.this.status +} + +% Here we write out all the LaTeX code that we will need. The most involved +% code sequences are those that control the alternate interword spacing and +% foreign language hyphenation patterns. The heavy use of \providecommand +% gives users a way to override the defaults. Special thanks to Javier Bezos, +% Johannes Braams, Robin Fairburns, Heiko Oberdiek, Donald Arseneau and all +% the other gurus on comp.text.tex for their help and advice on the topic of +% \selectlanguage, Babel and BibTeX. +FUNCTION {begin.bib} +{ preamble$ empty$ 'skip$ + { preamble$ write$ newline$ } + if$ + "\begin{thebibliography}{" longest.label * "}" * + write$ newline$ + "\providecommand{\url}[1]{#1}" + write$ newline$ + "\def\UrlFont{\rmfamily}" + write$ newline$ + "\providecommand{\newblock}{\relax}" + write$ newline$ + "\providecommand{\bibinfo}[2]{#2}" + write$ newline$ + "\providecommand\BIBentrySTDinterwordspacing{\spaceskip=0pt\relax}" + write$ newline$ + "\providecommand\BIBentryALTinterwordstretchfactor{" + ALTinterwordstretchfactor * "}" * + write$ newline$ + "\providecommand\BIBentryALTinterwordspacing{\spaceskip=\fontdimen2\font plus " + write$ newline$ + "\BIBentryALTinterwordstretchfactor\fontdimen3\font minus \fontdimen4\font\relax}" + write$ newline$ + "\providecommand\BIBforeignlanguage[2]{{%" + write$ newline$ + "\expandafter\ifx\csname l@#1\endcsname\relax" + write$ newline$ + "\typeout{** WARNING: IEEEtran.bst: No hyphenation pattern has been}%" + write$ newline$ + "\typeout{** loaded for the language `#1'. Using the pattern for}%" + write$ newline$ + "\typeout{** the default language instead.}%" + write$ newline$ + "\else" + write$ newline$ + "\language=\csname l@#1\endcsname" + write$ newline$ + "\fi" + write$ newline$ + "#2}}" + write$ newline$ +} + +FUNCTION {end.bib} +{ newline$ "\end{thebibliography}" write$ newline$ } + +FUNCTION {if.url.alt.interword.spacing} +{ is.use.alt.interword.spacing + {url empty$ 'skip$ {"\BIBentryALTinterwordspacing" write$ newline$} if$} + { skip$ } + if$ +} + +FUNCTION {if.url.std.interword.spacing} +{ is.use.alt.interword.spacing + {url empty$ 'skip$ {"\BIBentrySTDinterwordspacing" write$ newline$} if$} + { skip$ } + if$ +} + + + + +%%%%%%%%%%%%%%%%%%%%%%%% +%% LONGEST LABEL PASS %% +%%%%%%%%%%%%%%%%%%%%%%%% + +FUNCTION {initialize.longest.label} +{ "" 'longest.label := + #1 'number.label := + #0 'longest.label.width := +} + +FUNCTION {longest.label.pass} +{ number.label int.to.str$ 'label := + number.label #1 + 'number.label := + label width$ longest.label.width > + { label 'longest.label := + label width$ 'longest.label.width := + } + 'skip$ + if$ +} + + + + +%%%%%%%%%%%%%%%%%%%%% +%% FORMAT HANDLERS %% +%%%%%%%%%%%%%%%%%%%%% + +%% Lower Level Formats (used by higher level formats) + +FUNCTION {format.address.org.or.pub.date} +{ 't := + "" + year empty$ + { "empty year in " cite$ * warning$ } + { skip$ } + if$ + address empty$ t empty$ and + year empty$ and month empty$ and + { skip$ } + { this.to.prev.status + this.status.std + cap.status.std + address "address" bibinfo.check * + t empty$ + { skip$ } + { punct.period 'prev.status.punct := + space.large 'prev.status.space := + address empty$ + { skip$ } + { ": " * } + if$ + t * + } + if$ + year empty$ month empty$ and + { skip$ } + { t empty$ address empty$ and + { skip$ } + { ", " * } + if$ + month empty$ + { year empty$ + { skip$ } + { year "year" bibinfo.check * } + if$ + } + { month "month" bibinfo.check * + year empty$ + { skip$ } + { " " * year "year" bibinfo.check * } + if$ + } + if$ + } + if$ + } + if$ +} + + +FUNCTION {format.names} +{ 'bibinfo := + duplicate$ empty$ 'skip$ { + this.to.prev.status + this.status.std + 's := + "" 't := + #1 'nameptr := + s num.names$ 'numnames := + numnames 'namesleft := + { namesleft #0 > } + { s nameptr + name.format.string + format.name$ + bibinfo bibinfo.check + 't := + nameptr #1 > + { nameptr num.names.shown.with.forced.et.al #1 + = + numnames max.num.names.before.forced.et.al > + is.forced.et.al and and + { "others" 't := + #1 'namesleft := + } + { skip$ } + if$ + namesleft #1 > + { ", " * t do.name.latex.cmd * } + { + numnames #2 > + { "," * } + 'skip$ + if$ + s nameptr "{ll}" format.name$ duplicate$ "others" = + { 't := } + { pop$ } + if$ + t "others" = + { + " " * bbl.etal emphasize * + } + { + bbl.and + space.word * t do.name.latex.cmd * + } + if$ + } + if$ + } + { t do.name.latex.cmd } + if$ + nameptr #1 + 'nameptr := + namesleft #1 - 'namesleft := + } + while$ + cap.status.std + } if$ +} + + + + +%% Higher Level Formats + +%% addresses/locations + +FUNCTION {format.address} +{ address duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + cap.status.std + } + if$ +} + + + +%% author/editor names + +FUNCTION {format.authors}{ author "author" format.names } + +FUNCTION {format.editors} +{ editor "editor" format.names duplicate$ empty$ 'skip$ + { ", " * + get.bbl.editor + capitalize + * + } + if$ +} + + + +%% date + +FUNCTION {format.date} +{ + month "month" bibinfo.check duplicate$ empty$ + year "year" bibinfo.check duplicate$ empty$ + { swap$ 'skip$ + { this.to.prev.status + this.status.std + cap.status.std + "there's a month but no year in " cite$ * warning$ } + if$ + * + } + { this.to.prev.status + this.status.std + cap.status.std + swap$ 'skip$ + { + swap$ + " " * swap$ + } + if$ + * + } + if$ +} + +FUNCTION {format.date.electronic} +{ month "month" bibinfo.check duplicate$ empty$ + year "year" bibinfo.check duplicate$ empty$ + { swap$ + { pop$ } + { "there's a month but no year in " cite$ * warning$ + pop$ ")" * "(" swap$ * + this.to.prev.status + punct.no 'this.status.punct := + space.normal 'this.status.space := + quote.no 'this.status.quote := + cap.yes 'status.cap := + } + if$ + } + { swap$ + { swap$ pop$ ")" * "(" swap$ * } + { "(" swap$ * ", " * swap$ * ")" * } + if$ + this.to.prev.status + punct.no 'this.status.punct := + space.normal 'this.status.space := + quote.no 'this.status.quote := + cap.yes 'status.cap := + } + if$ +} + + + +%% edition/title + +% Note: IEEE considers the edition to be closely associated with +% the title of a book. So, in IEEEtran.bst the edition is normally handled +% within the formatting of the title. The format.edition function is +% retained here for possible future use. +FUNCTION {format.edition} +{ edition duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + convert.edition + status.cap + { "t" } + { "l" } + if$ change.case$ + "edition" bibinfo.check + "~" * bbl.edition * + cap.status.std + } + if$ +} + +% This is used to format the booktitle of a conference proceedings. +% Here we use the "intype" field to provide the user a way to +% override the word "in" (e.g., with things like "presented at") +% Use of intype stops the emphasis of the booktitle to indicate that +% we no longer mean the written conference proceedings, but the +% conference itself. +FUNCTION {format.in.booktitle} +{ booktitle "booktitle" bibinfo.check duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + select.language + intype missing$ + { emphasize + bbl.in " " * + } + { intype " " * } + if$ + swap$ * + cap.status.std + } + if$ +} + +% This is used to format the booktitle of collection. +% Here the "intype" field is not supported, but "edition" is. +FUNCTION {format.in.booktitle.edition} +{ booktitle "booktitle" bibinfo.check duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + select.language + emphasize + edition empty$ 'skip$ + { ", " * + edition + convert.edition + "l" change.case$ + * "~" * bbl.edition * + } + if$ + bbl.in " " * swap$ * + cap.status.std + } + if$ +} + +FUNCTION {format.article.title} +{ title duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + "t" change.case$ + } + if$ + "title" bibinfo.check + duplicate$ empty$ 'skip$ + { quote.close 'this.status.quote := + is.last.char.not.punct + { punct.std 'this.status.punct := } + { punct.no 'this.status.punct := } + if$ + select.language + "``" swap$ * + cap.status.std + } + if$ +} + +FUNCTION {format.article.title.electronic} +{ title duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + cap.status.std + "t" change.case$ + } + if$ + "title" bibinfo.check + duplicate$ empty$ + { skip$ } + { select.language } + if$ +} + +FUNCTION {format.book.title.edition} +{ title "title" bibinfo.check + duplicate$ empty$ + { "empty title in " cite$ * warning$ } + { this.to.prev.status + this.status.std + select.language + emphasize + edition empty$ 'skip$ + { ", " * + edition + convert.edition + status.cap + { "t" } + { "l" } + if$ + change.case$ + * "~" * bbl.edition * + } + if$ + cap.status.std + } + if$ +} + +FUNCTION {format.book.title} +{ title "title" bibinfo.check + duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + cap.status.std + select.language + emphasize + } + if$ +} + + + +%% journal + +FUNCTION {format.journal} +{ journal duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + cap.status.std + select.language + emphasize + } + if$ +} + + + +%% how published + +FUNCTION {format.howpublished} +{ howpublished duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + cap.status.std + } + if$ +} + + + +%% institutions/organization/publishers/school + +FUNCTION {format.institution} +{ institution duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + cap.status.std + } + if$ +} + +FUNCTION {format.organization} +{ organization duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + cap.status.std + } + if$ +} + +FUNCTION {format.address.publisher.date} +{ publisher "publisher" bibinfo.warn format.address.org.or.pub.date } + +FUNCTION {format.address.publisher.date.nowarn} +{ publisher "publisher" bibinfo.check format.address.org.or.pub.date } + +FUNCTION {format.address.organization.date} +{ organization "organization" bibinfo.check format.address.org.or.pub.date } + +FUNCTION {format.school} +{ school duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + cap.status.std + } + if$ +} + + + +%% volume/number/series/chapter/pages + +FUNCTION {format.volume} +{ volume empty.field.to.null.string + duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + bbl.volume + status.cap + { capitalize } + { skip$ } + if$ + swap$ tie.or.space.prefix + "volume" bibinfo.check + * * + cap.status.std + } + if$ +} + +FUNCTION {format.number} +{ number empty.field.to.null.string + duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + status.cap + { bbl.number capitalize } + { bbl.number } + if$ + swap$ tie.or.space.prefix + "number" bibinfo.check + * * + cap.status.std + } + if$ +} + +FUNCTION {format.number.if.use.for.article} +{ is.use.number.for.article + { format.number } + { "" } + if$ +} + +% IEEE does not seem to tie the series so closely with the volume +% and number as is done in other bibliography styles. Instead the +% series is treated somewhat like an extension of the title. +FUNCTION {format.series} +{ series empty$ + { "" } + { this.to.prev.status + this.status.std + bbl.series " " * + series "series" bibinfo.check * + cap.status.std + } + if$ +} + + +FUNCTION {format.chapter} +{ chapter empty$ + { "" } + { this.to.prev.status + this.status.std + type empty$ + { bbl.chapter } + { type "l" change.case$ + "type" bibinfo.check + } + if$ + chapter tie.or.space.prefix + "chapter" bibinfo.check + * * + cap.status.std + } + if$ +} + + +% The intended use of format.paper is for paper numbers of inproceedings. +% The paper type can be overridden via the type field. +% We allow the type to be displayed even if the paper number is absent +% for things like "postdeadline paper" +FUNCTION {format.paper} +{ is.use.paper + { paper empty$ + { type empty$ + { "" } + { this.to.prev.status + this.status.std + type "type" bibinfo.check + cap.status.std + } + if$ + } + { this.to.prev.status + this.status.std + type empty$ + { bbl.paper } + { type "type" bibinfo.check } + if$ + " " * paper + "paper" bibinfo.check + * + cap.status.std + } + if$ + } + { "" } + if$ +} + + +FUNCTION {format.pages} +{ pages duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + duplicate$ is.multiple.pages + { + bbl.pages swap$ + n.dashify + } + { + bbl.page swap$ + } + if$ + tie.or.space.prefix + "pages" bibinfo.check + * * + cap.status.std + } + if$ +} + + + +%% technical report number + +FUNCTION {format.tech.report.number} +{ number "number" bibinfo.check + type duplicate$ empty$ + { pop$ + this.to.prev.status + this.status.std + cap.status.std + bbl.techrep + } + { skip$ } + if$ + "type" bibinfo.check + swap$ duplicate$ empty$ + { pop$ } + { this.to.prev.status + this.status.std + cap.status.std + tie.or.space.prefix * * } + if$ +} + + + +%% note + +FUNCTION {format.note} +{ note empty$ + { "" } + { this.to.prev.status + this.status.std + punct.period 'this.status.punct := + note #1 #1 substring$ + duplicate$ "{" = + { skip$ } + { status.cap + { "u" } + { "l" } + if$ + change.case$ + } + if$ + note #2 global.max$ substring$ * "note" bibinfo.check + cap.yes 'status.cap := + } + if$ +} + + + +%% patent + +FUNCTION {format.patent.date} +{ this.to.prev.status + this.status.std + year empty$ + { monthfiled duplicate$ empty$ + { "monthfiled" bibinfo.check pop$ "" } + { "monthfiled" bibinfo.check } + if$ + dayfiled duplicate$ empty$ + { "dayfiled" bibinfo.check pop$ "" * } + { "dayfiled" bibinfo.check + monthfiled empty$ + { "dayfiled without a monthfiled in " cite$ * warning$ + * + } + { " " swap$ * * } + if$ + } + if$ + yearfiled empty$ + { "no year or yearfiled in " cite$ * warning$ } + { yearfiled "yearfiled" bibinfo.check + swap$ + duplicate$ empty$ + { pop$ } + { ", " * swap$ * } + if$ + } + if$ + } + { month duplicate$ empty$ + { "month" bibinfo.check pop$ "" } + { "month" bibinfo.check } + if$ + day duplicate$ empty$ + { "day" bibinfo.check pop$ "" * } + { "day" bibinfo.check + month empty$ + { "day without a month in " cite$ * warning$ + * + } + { " " swap$ * * } + if$ + } + if$ + year "year" bibinfo.check + swap$ + duplicate$ empty$ + { pop$ } + { ", " * swap$ * } + if$ + } + if$ + cap.status.std +} + +FUNCTION {format.patent.nationality.type.number} +{ this.to.prev.status + this.status.std + nationality duplicate$ empty$ + { "nationality" bibinfo.warn pop$ "" } + { "nationality" bibinfo.check + duplicate$ "l" change.case$ "united states" = + { pop$ bbl.patentUS } + { skip$ } + if$ + " " * + } + if$ + type empty$ + { bbl.patent "type" bibinfo.check } + { type "type" bibinfo.check } + if$ + * + number duplicate$ empty$ + { "number" bibinfo.warn pop$ } + { "number" bibinfo.check + large.number.separate + swap$ " " * swap$ * + } + if$ + cap.status.std +} + + + +%% standard + +FUNCTION {format.organization.institution.standard.type.number} +{ this.to.prev.status + this.status.std + organization duplicate$ empty$ + { pop$ + institution duplicate$ empty$ + { "institution" bibinfo.warn } + { "institution" bibinfo.warn " " * } + if$ + } + { "organization" bibinfo.warn " " * } + if$ + type empty$ + { bbl.standard "type" bibinfo.check } + { type "type" bibinfo.check } + if$ + * + number duplicate$ empty$ + { "number" bibinfo.check pop$ } + { "number" bibinfo.check + large.number.separate + swap$ " " * swap$ * + } + if$ + cap.status.std +} + +FUNCTION {format.revision} +{ revision empty$ + { "" } + { this.to.prev.status + this.status.std + bbl.revision + revision tie.or.space.prefix + "revision" bibinfo.check + * * + cap.status.std + } + if$ +} + + +%% thesis + +FUNCTION {format.master.thesis.type} +{ this.to.prev.status + this.status.std + type empty$ + { + bbl.mthesis + } + { + type "type" bibinfo.check + } + if$ +cap.status.std +} + +FUNCTION {format.phd.thesis.type} +{ this.to.prev.status + this.status.std + type empty$ + { + bbl.phdthesis + } + { + type "type" bibinfo.check + } + if$ +cap.status.std +} + + + +%% URL + +FUNCTION {format.url} +{ url empty$ + { "" } + { this.to.prev.status + this.status.std + cap.yes 'status.cap := + bbl.urlprefix " " * + "\url{" * url * "}" * + punct.no 'this.status.punct := + punct.period 'prev.status.punct := + space.normal 'this.status.space := + space.normal 'prev.status.space := + quote.no 'this.status.quote := + } + if$ +} + + + + +%%%%%%%%%%%%%%%%%%%% +%% ENTRY HANDLERS %% +%%%%%%%%%%%%%%%%%%%% + + +% Note: In many journals, IEEE (or the authors) tend not to show the number +% for articles, so the display of the number is controlled here by the +% switch "is.use.number.for.article" +FUNCTION {article} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors "author" output.warn + name.or.dash + format.article.title "title" output.warn + format.journal "journal" bibinfo.check "journal" output.warn + format.volume output + format.number.if.use.for.article output + format.pages output + format.date "year" output.warn + format.note output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {book} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + author empty$ + { format.editors "author and editor" output.warn } + { format.authors output.nonnull } + if$ + name.or.dash + format.book.title.edition output + format.series output + author empty$ + { skip$ } + { format.editors output } + if$ + format.address.publisher.date output + format.volume output + format.number output + format.note output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {booklet} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors output + name.or.dash + format.article.title "title" output.warn + format.howpublished "howpublished" bibinfo.check output + format.organization "organization" bibinfo.check output + format.address "address" bibinfo.check output + format.date output + format.note output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {electronic} +{ std.status.using.period + start.entry + if.url.alt.interword.spacing + format.authors output + name.or.dash + format.date.electronic output + format.article.title.electronic output + format.howpublished "howpublished" bibinfo.check output + format.organization "organization" bibinfo.check output + format.address "address" bibinfo.check output + format.note output + format.url output + fin.entry + empty.entry.warn + if.url.std.interword.spacing +} + +FUNCTION {inbook} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + author empty$ + { format.editors "author and editor" output.warn } + { format.authors output.nonnull } + if$ + name.or.dash + format.book.title.edition output + format.series output + format.address.publisher.date output + format.volume output + format.number output + format.chapter output + format.pages output + format.note output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {incollection} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors "author" output.warn + name.or.dash + format.article.title "title" output.warn + format.in.booktitle.edition "booktitle" output.warn + format.series output + format.editors output + format.address.publisher.date.nowarn output + format.volume output + format.number output + format.chapter output + format.pages output + format.note output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {inproceedings} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors "author" output.warn + name.or.dash + format.article.title "title" output.warn + format.in.booktitle "booktitle" output.warn + format.series output + format.editors output + format.volume output + format.number output + publisher empty$ + { format.address.organization.date output } + { format.organization "organization" bibinfo.check output + format.address.publisher.date output + } + if$ + format.paper output + format.pages output + format.note output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {manual} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors output + name.or.dash + format.book.title.edition "title" output.warn + format.howpublished "howpublished" bibinfo.check output + format.organization "organization" bibinfo.check output + format.address "address" bibinfo.check output + format.date output + format.note output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {mastersthesis} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors "author" output.warn + name.or.dash + format.article.title "title" output.warn + format.master.thesis.type output.nonnull + format.school "school" bibinfo.warn output + format.address "address" bibinfo.check output + format.date "year" output.warn + format.note output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {misc} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors output + name.or.dash + format.article.title output + format.howpublished "howpublished" bibinfo.check output + format.organization "organization" bibinfo.check output + format.address "address" bibinfo.check output + format.pages output + format.date output + format.note output + format.url output + fin.entry + empty.entry.warn + if.url.std.interword.spacing +} + +FUNCTION {patent} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors output + name.or.dash + format.article.title output + format.patent.nationality.type.number output + format.patent.date output + format.note output + format.url output + fin.entry + empty.entry.warn + if.url.std.interword.spacing +} + +FUNCTION {periodical} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.editors output + name.or.dash + format.book.title "title" output.warn + format.series output + format.volume output + format.number output + format.organization "organization" bibinfo.check output + format.date "year" output.warn + format.note output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {phdthesis} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors "author" output.warn + name.or.dash + format.article.title "title" output.warn + format.phd.thesis.type output.nonnull + format.school "school" bibinfo.warn output + format.address "address" bibinfo.check output + format.date "year" output.warn + format.note output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {proceedings} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.editors output + name.or.dash + format.book.title "title" output.warn + format.series output + format.volume output + format.number output + publisher empty$ + { format.address.organization.date output } + { format.organization "organization" bibinfo.check output + format.address.publisher.date output + } + if$ + format.note output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {standard} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors output + name.or.dash + format.book.title "title" output.warn + format.howpublished "howpublished" bibinfo.check output + format.organization.institution.standard.type.number output + format.revision output + format.date output + format.note output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {techreport} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors "author" output.warn + name.or.dash + format.article.title "title" output.warn + format.howpublished "howpublished" bibinfo.check output + format.institution "institution" bibinfo.warn output + format.address "address" bibinfo.check output + format.tech.report.number output.nonnull + format.date "year" output.warn + format.note output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {unpublished} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors "author" output.warn + name.or.dash + format.article.title "title" output.warn + format.date output + format.note "note" output.warn + format.url output + fin.entry + if.url.std.interword.spacing +} + + +% The special entry type which provides the user interface to the +% BST controls +FUNCTION {IEEEtranBSTCTL} +{ is.print.banners.to.terminal + { "** IEEEtran BST control entry " quote$ * cite$ * quote$ * " detected." * + top$ + } + { skip$ } + if$ + CTLuse_article_number + empty$ + { skip$ } + { CTLuse_article_number + yes.no.to.int + 'is.use.number.for.article := + } + if$ + CTLuse_paper + empty$ + { skip$ } + { CTLuse_paper + yes.no.to.int + 'is.use.paper := + } + if$ + CTLuse_forced_etal + empty$ + { skip$ } + { CTLuse_forced_etal + yes.no.to.int + 'is.forced.et.al := + } + if$ + CTLmax_names_forced_etal + empty$ + { skip$ } + { CTLmax_names_forced_etal + string.to.integer + 'max.num.names.before.forced.et.al := + } + if$ + CTLnames_show_etal + empty$ + { skip$ } + { CTLnames_show_etal + string.to.integer + 'num.names.shown.with.forced.et.al := + } + if$ + CTLuse_alt_spacing + empty$ + { skip$ } + { CTLuse_alt_spacing + yes.no.to.int + 'is.use.alt.interword.spacing := + } + if$ + CTLalt_stretch_factor + empty$ + { skip$ } + { CTLalt_stretch_factor + 'ALTinterwordstretchfactor := + "\renewcommand\BIBentryALTinterwordstretchfactor{" + ALTinterwordstretchfactor * "}" * + write$ newline$ + } + if$ + CTLdash_repeated_names + empty$ + { skip$ } + { CTLdash_repeated_names + yes.no.to.int + 'is.dash.repeated.names := + } + if$ + CTLname_format_string + empty$ + { skip$ } + { CTLname_format_string + 'name.format.string := + } + if$ + CTLname_latex_cmd + empty$ + { skip$ } + { CTLname_latex_cmd + 'name.latex.cmd := + } + if$ + + + num.names.shown.with.forced.et.al max.num.names.before.forced.et.al > + { "CTLnames_show_etal cannot be greater than CTLmax_names_forced_etal in " cite$ * warning$ + max.num.names.before.forced.et.al 'num.names.shown.with.forced.et.al := + } + { skip$ } + if$ +} + + +%%%%%%%%%%%%%%%%%%% +%% ENTRY ALIASES %% +%%%%%%%%%%%%%%%%%%% +FUNCTION {conference}{inproceedings} +FUNCTION {online}{electronic} +FUNCTION {internet}{electronic} +FUNCTION {webpage}{electronic} +FUNCTION {default.type}{misc} + + + +%%%%%%%%%%%%%%%%%% +%% MAIN PROGRAM %% +%%%%%%%%%%%%%%%%%% + +READ + +EXECUTE {initialize.controls} +EXECUTE {initialize.status.constants} +EXECUTE {banner.message} + +EXECUTE {initialize.longest.label} +ITERATE {longest.label.pass} + +EXECUTE {begin.bib} +ITERATE {call.type$} +EXECUTE {end.bib} + +EXECUTE{completed.message} + + +%% That's all folks, mds. diff --git a/abstract.tex b/abstract.tex new file mode 100644 index 0000000..06de013 --- /dev/null +++ b/abstract.tex @@ -0,0 +1,5 @@ +This assignment guides students through a reproducible DevOps activity. It +defines the learning objectives, environment boundary, workflow, evidence, +reflection, and submission criteria. Replace bracketed text with assignment- +specific facts before release. Students should be able to recreate the work +from the submitted automation and runbook rather than from undocumented manual steps. diff --git a/cornell.cls b/cornell.cls new file mode 100644 index 0000000..79b37eb --- /dev/null +++ b/cornell.cls @@ -0,0 +1,367 @@ +%% +%% This is file `cornell.cls', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% cornell.dtx (with options: `class') +%% +%% IMPORTANT NOTICE: +%% +%% For the copyright see the source file. +%% +%% Any modified versions of this file must be renamed +%% with new filenames distinct from cornell.cls. +%% +%% For distribution of the original source see the terms +%% for copying and modification in the file cornell.dtx. +%% +%% This generated file may be distributed as long as the +%% original source files, as listed above, are part of the +%% same distribution. (The sources need not necessarily be +%% in the same archive or directory.) +%% Document class `cornell' to use with LaTeX 2e. +%% Based on `crnlphd' class. The following is from the file `crnlphd.dtx': +%% Based loosely on old cuphdthesis style file. +%% Found to give good results, according to the thesis secretary. +%% File: crnlphd.dtx Copyright (C) 1994 Sergio Gelato +%% Made available without any warranty, express or implied. +%% Modifications +%% 03/26/98 Mike Heisler +%% Conform to Eric's final version. Margins are subject to +%% The whim of the printer. +%% 10/10/97 Mike Heisler and Eric Dahl +%% Altered footnotesize and changed the Acknowledgement and +%% Biographical titles per thesis secretary guideline that +%% they must match the rest of the document, i.e. flush left +%% and capitalized rather than all caps +%% 05/21/97 Mike Heisler +%% Added a 'papers' option to handle bibliographis as sections +%% at the end of each chapter. Reduced top margin. +%% +%% $Id$ +%% \CharacterTable +%% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z +%% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z +%% Digits \0\1\2\3\4\5\6\7\8\9 +%% Exclamation \! Double quote \" Hash (number) \# +%% Dollar \$ Percent \% Ampersand \& +%% Acute accent \' Left paren \( Right paren \) +%% Asterisk \* Plus \+ Comma \, +%% Minus \- Point \. Solidus \/ +%% Colon \: Semicolon \; Less than \< +%% Equals \= Greater than \> Question mark \? +%% Commercial at \@ Left bracket \[ Backslash \\ +%% Right bracket \] Circumflex \^ Underscore \_ +%% Grave accent \` Left brace \{ Vertical bar \| +%% Right brace \} Tilde \~} +%% +\NeedsTeXFormat{LaTeX2e}[1995/12/01] +\ProvidesClass{cornell} +[1998/03/26 v2.0 + Cornell University thesis class] +\newif\ifphd +\DeclareOption{phd}{\phdtrue} +\DeclareOption{master}{\phdfalse} +\ExecuteOptions{phd} +\newif\ifpapers +\DeclareOption{papers}{\paperstrue} +\DeclareOption{10pt}{% + \OptionNotUsed% + \ClassWarningNoLine{cornell}{Font size 10pt not allowed; using 12pt}% +} +\DeclareOption{11pt}{% + \OptionNotUsed% + \ClassWarningNoLine{cornell}{Font size 11pt not allowed; using 12pt}% +} +\newcommand{\prelim@contents}[1]{} +\DeclareOption{tocprelim}{% + \renewcommand{\prelim@contents}[1]{\addcontentsline{toc}{section}{#1}} +} +\DeclareOption*{% + \PassOptionsToClass{\CurrentOption}{report}% +} +\ProcessOptions + +\LoadClass[12pt]{report}[1994/06/01] +\renewcommand{\defaultscriptratio}{.75} +\renewcommand{\defaultscriptscriptratio}{.6} +\setlength\headsep{25\p@} +\if@twocolumn +\else + \setlength\oddsidemargin{0in} + \setlength\evensidemargin{0in} + \setlength\textwidth{6.5in} + \setlength\topmargin{-0.5in} + \setlength\headheight{0.2in} + \setlength\headsep{0.35in} + \setlength\textheight{8.85in} + \setlength\footskip{0.5in} + \setlength\marginparwidth{0.85in} + \setlength\marginparsep{0.125in} +\fi +\if@compatibility + \setlength\topmargin{0\p@} +\else +\fi +\newcommand{\ps@cornell}{% +\def\@oddhead{{\slshape\rightmark}\hfil\thepage}% +\def\@oddfoot{}% +\def\@evenhead{\thepage\hfil{\slshape\leftmark}}% +\def\@evenfoot{}% +\def\chaptermark##1{}% +\def\sectionmark##1{}% +} +\newcommand{\ps@cornellc}{% +\def\@oddhead{\hfil\thepage\hfil}% +\def\@oddfoot{}% +\def\@evenhead{\@oddhead}% +\def\@evenfoot{}% +\def\chaptermark##1{}% +\def\sectionmark##1{}% +} +\raggedbottom +\newcommand{\@prolformat}[1]{{\begin{flushleft} \Huge #1 \end{flushleft}} } +\newcommand{\ackname}{\@prolformat{Acknowledgements}} +\newcommand{\bioname}{\@prolformat{Biographical Sketch}} +\renewcommand{\contentsname}{\@prolformat{Table of Contents}} +\renewcommand{\listtablename}{\@prolformat{List of Tables}} +\renewcommand{\listfigurename}{\@prolformat{List of Figures}} +\renewcommand{\l@figure}{\@dottedtocline{1}{1.5em}{2.6em}} +\let\l@table\l@figure + +\renewenvironment{thebibliography}[1] + {\ifpapers \clearpage \section*{\bibname% + \@mkboth{\uppercase{\bibname}}{\uppercase{\bibname}}}% + \else% + \chapter*{\bibname% + \@mkboth{\uppercase{\bibname}}{\uppercase{\bibname}}}% + \fi% + \list{\@biblabel{\arabic{enumiv}}}% + {\settowidth\labelwidth{\@biblabel{#1}}% + \leftmargin\labelwidth + \advance\leftmargin\labelsep + \@openbib@code + \usecounter{enumiv}% + \let\p@enumiv\@empty + \renewcommand\theenumiv{\arabic{enumiv}}}% + \sloppy\clubpenalty4000\widowpenalty4000% + \sfcode`\.\@m\relax + \ifpapers% + \addcontentsline{toc}{section}{\bibname}% + \else% + \addcontentsline{toc}{chapter}{\bibname}% + \fi + \singlespacing} + {\def\@noitemerr + {\@latex@warning{Empty `thebibliography' environment}}% + \normalspacing + \endlist} + +\newcommand{\@titlesize}{\Large} +\newcommand{\@subtitlesize}{\large} +\newcommand{\@authorsize}{\normalsize} % No Pharaoh he. +\newcommand{\@conferralmonth}{January} +\newcommand{\@conferralyear}{} + +\newcommand{\titlesize}[1]{\renewcommand{\@titlesize}{#1}} +\newcommand{\subtitlesize}[1]{\renewcommand{\@subtitlesize}{#1}} +\newcommand{\authorsize}[1]{\renewcommand{\@authorsize}{#1}} +\newcommand{\conferraldate}[2]{% + \renewcommand{\@conferralmonth}{#1} + \renewcommand{\@conferralyear}{#2} +} +\newcommand{\@degreefield}{Master of Science} %CHANGED +\newcommand{\degreefield}[1]{\renewcommand{\@degreefield}{#1}} %CHANGED + +\renewcommand{\maketitle}{% + \begin{titlepage}% + \vspace*{-0.24in} + \begin{center}% + \@titlesize \@title + \end{center} + \vfill + %\begin{center} + %\@subtitlesize + %A \ifphd Dissertation \else Thesis \fi \\ %CHANGED + %Presented to the Faculty of the Graduate School \\ + %of Cornell University \\ + %in Partial Fulfillment of the Requirements for the Degree of \\ + %\ifphd Doctor of Philosophy \else \@degreefield \fi %CHANGED + %\end{center} + \vfill + \begin{center} + \@authorsize + by \\ + \@author \\ + \@conferralmonth\ \@conferralyear + \end{center} + \vspace*{0.26in} + \end{titlepage} +} + +\renewenvironment{titlepage}{% + \typeout{Title page} + \pagestyle{empty} + \doublespacing +}{% + \normalspacing\clearpage +} + + +\newenvironment{copyrightpage}{% + \typeout{Copyleft page} + \pagestyle{empty} + \null\vfil + \begin{center} +}{% + \end{center} + \vfil\null + \clearpage +} + +\newcommand{\makecopyright}{% + \begin{copyrightpage} + \copyright\ \@copyrightholder\ \@copyrightyear \\ + ALL RIGHTS RESERVED \\[.5in] + \end{copyrightpage} +} +\newcommand{\@copyrightholder}{\@author} +\newcommand{\@copyrightyear}{\@conferralyear} + +\newcommand{\copyrightholder}[1]{\renewcommand{\@copyrightholder}{#1}} +\newcommand{\copyrightyear}[1]{\renewcommand{\@copyrightyear}{#1}} + + +\newlength{\@abhdskip} +\renewenvironment{abstract}{% + \typeout{Abstract} + \singlespacing + \ifphd %CHANGED + \setlength{\@abhdskip}{.25in} + \addtolength{\@abhdskip}{-\topmargin} + \vspace*{\@abhdskip} + \begin{center} + \@abstracttitle \\ + \ \\ + \@author \\ + \@conferralyear + \end{center} + \vspace{.25in} + \else %CHANGED + \chapter*{% + \begin{center} + \normalsize + ABSTRACT + \end{center} + } + \par + \fi %CHANGED + \pagestyle{empty} + \thispagestyle{empty} +}{% + \clearpage +} + +\newcommand{\@abstracttitle}{\@title} +\newcommand{\abstracttitle}[1]{\renewcommand{\@abstracttitle}{#1}} + + +\newenvironment{biosketch}{% + \typeout{Vita} + \pagestyle{plain} + \pagenumbering{roman} + \setcounter{page}{3} + \prelim@contents{Biographical Sketch} + \chapter*{% +\bioname + } + \par +}{% + \clearpage +} + +\newenvironment{dedication}{% + \prelim@contents{Dedication} + \null\vfil + \begin{center} +}{ + \end{center} + \vfil\null + \clearpage +} + +\newenvironment{acknowledgements}{% + \prelim@contents{Acknowledgments} + \chapter*{% +\ackname + } + \par +}{% + \cleardoublepage +} + +\newcommand{\contentspage}{% + \singlespacing + \label{toc} + \prelim@contents{\contentsname} + \tableofcontents + \normalspacing + \clearpage +} + +\newcommand{\tablelistpage}{% + \singlespacing + \label{lot} + \prelim@contents{\listtablename} + \listoftables + \normalspacing + \clearpage +} + +\newcommand{\figurelistpage}{% + \singlespacing + \label{lof} + \prelim@contents{\listfigurename} + \listoffigures + \normalspacing + \clearpage +} +\newcommand{\abbrlist}{% + \singlespacing + \prelim@contents{List of Abbreviations} + \chapter*{List of Abbreviations} +} + +\newcommand{\symlist}{% + \singlespacing + \prelim@contents{List of Symbols} + \chapter*{List of Symbols} +} + +\newcommand{\preface}{% + \singlespacing + \prelim@contents{Preface} + \chapter*{Preface} +} + +\newcommand{\singlespacing}{% + \let\CS=\@currsize\renewcommand{\baselinestretch}{1.0}\tiny\CS} +\newcommand{\singlespacingplus}{% + \let\CS=\@currsize\renewcommand{\baselinestretch}{1.25}\tiny\CS} +\newcommand{\doublespacing}{% + \let\CS=\@currsize\renewcommand{\baselinestretch}{1.75}\tiny\CS} +\newcommand{\realdoublespacing}{% + \let\CS=\@currsize\renewcommand{\baselinestretch}{2}\tiny\CS} +\newcommand{\normalspacing}{\doublespacing} +\newcommand{\footnotespacing}{\singlespacing} +\newcommand{\changespacing}[2]{% + \renewcommand{#1}{% + \let\CS=\@currsize\renewcommand{\baselinestretch}{#2}\tiny\CS}% +} +\newcommand{\changenormalspacing}[1]{\renewcommand{\normalspacing}{#1}} +\normalspacing + +\endinput +%% +%% End of file `cornell.cls'. diff --git a/devopsAIAgentGuide.tex b/devopsAIAgentGuide.tex new file mode 100644 index 0000000..608fffe --- /dev/null +++ b/devopsAIAgentGuide.tex @@ -0,0 +1,107 @@ +\chapter{AI Agent Usage Guide} +\ChapterLabel{AIAgentGuide} +\index{AI agent} +\index{AI agent!DevOps workflow} +\index{Appendix!AI Agent Usage Guide} + +\section{How to Use This Appendix} +An AI agent that creates, reviews, or maintains an assignment shall read this +file first. It shall identify the task in the routing table, read the minimum +authoritative sources, and expand context only for a discovered dependency or +inconsistency. This guide is maintained in LaTeX so it is visible, versioned, +and reviewable with the assignment. + +\section{Governing Principles} +The authored LaTeX files, versioned automation, and approved assignment +materials are authoritative. The PDF is a review artifact and shall not be +edited directly. AI may draft, explain, analyze, check consistency, and assist +with builds. It shall not invent completion, evidence, access, costs, grades, +approvals, command output, security posture, or operational results. + +\section{Chapter File Convention} +\index{AI agent!chapter file convention} +Every assignment chapter shall be stored in exactly one file named with the +\texttt{devops} prefix, a PascalCase chapter name, and the \texttt{.tex} +suffix. For example, Chapter~2 is fully contained in +\path{devopsExampleAssignment.tex}. A chapter file shall begin with its +\texttt{\string\chapter\{...\}} command and contain all of that chapter's +sections and subsections. Do not split one chapter across files, create +section-only \texttt{.tex} files, or use \texttt{\string\input} or +\texttt{\string\include} to assemble a chapter from smaller fragments. + +Supporting non-chapter files may use a different name only when they are not +chapter content: \texttt{prologue.tex}, \texttt{abstract.tex}, +\texttt{devopsGlossary.tex}, and \texttt{devopsReferences.bib} are examples. +Appendix chapters follow the same chapter-file convention. + +\section{AI Quick Start} +\begin{enumerate} +\item Read this guide and identify the requested outcome. +\item Select the closest task below and load only its listed sources. +\item Inspect supplied facts and report consequential gaps or assumptions. +\item Make narrowly scoped changes; preserve stable IDs, glossary terms, and history. +\item Never request, print, store, or commit credentials, tokens, personal data, or production data. +\item Build the complete PDF, inspect the log, visually inspect affected pages, and record material AI use in \ChapterRef{AIPromptLog}. +\end{enumerate} + +\section{Task Routing} +\small +\begin{tabularx}{\linewidth}{L{4.0cm}Y} +\caption{AI Task-Routing Table\label{Table:AITaskRouting}}\\ +\toprule \textbf{Task} & \textbf{Minimum authoritative sources}\\ \midrule +Initialize an assignment & \texttt{devopsAssignment.tex}, \texttt{prologue.tex}, \texttt{devopsIntroduction.tex}, \texttt{devopsExampleAssignment.tex}, and the instructor's assignment facts.\\ +Develop a workflow & \texttt{devopsExampleAssignment.tex}, source repository materials, and authorized environment constraints.\\ +Define evidence & \texttt{devopsExampleAssignment.tex} and controlled execution outputs.\\ +Review a retrospective & \texttt{devopsExampleAssignment.tex} and the submitted workflow or runbook.\\ +Edit AI guidance & \texttt{devopsAIAgentGuide.tex}, \texttt{devopsAIPromptLog.tex}, \texttt{devopsDocumentGuide.tex}, and \texttt{devopsAssignment.tex}.\\ +Compile or troubleshoot & \texttt{devopsAssignment.tex}, \texttt{devopsDocumentGuide.tex}, the affected chapter, and the build log.\\ \bottomrule +\end{tabularx} +\normalsize + +\section{DevOps-Specific Rules} +\begin{enumerate} +\item Prefer versioned, repeatable automation over undocumented manual steps. +\item Treat deployment output, monitoring data, and screenshots as evidence only when they reflect an actual execution. +\item Design failure exercises to be isolated, reversible, and authorized. +\item Apply least privilege and never place secrets in LaTeX, source control, prompts, screenshots, or logs. +\item State expected cloud cost, cleanup action, and resource ownership for each remote-environment activity. +\item Identify whether a recommendation is a proposal, an instructor directive, or demonstrated evidence. +\end{enumerate} + +\section{Example AI Requests} +\subsection{Create an Assignment Brief} +\begin{verbatim} +Read devopsAIAgentGuide.tex and use the Initialize an Assignment context. +From the supplied SSW 590 objective and constraints, fill only supported +placeholders in the introduction and activity brief. Propose clear, observable +completion criteria, a safe cleanup action, and a rubric. Do not invent cloud +access, due dates, policy, costs, or approved tools. Update history, compile, +and report instructor decisions still needed. +\end{verbatim} + +\subsection{Review a Student Workflow} +\begin{verbatim} +Read devopsAIAgentGuide.tex and the workflow, evidence, and retrospective +chapters. Review the supplied repository and sanitized evidence for +reproducibility, least privilege, observability, rollback, and cleanup. +Separate verified facts from gaps and recommendations. Do not claim that an +unexecuted command passed, and do not request credentials or operate resources. +\end{verbatim} + +\section{Human Decisions and Information Boundaries} +The instructor retains authority over assignment scope, grading, due dates, +approved tooling, access, budgets, security posture, exceptions, and policy. +An AI agent shall surface alternatives and evidence, not represent a decision +as approved. Record material prompts, assumptions, corrections, and unresolved +issues in \ChapterRef{AIPromptLog}. + +\section{Completion Checklist} +\begin{itemize} +\item Scope, deliverables, environment, constraints, and cleanup are clear. +\item Activity identifiers and evidence references are valid and unique. +\item Examples contain no secrets, personal data, or unsafe production actions. +\item New controlled terms are added to the glossary and indexed. +\item The newest approved change is recorded in document history. +\item The complete build succeeds with no unresolved references or missing files. +\item A human reviews all decisions requiring instructional or operational authority. +\end{itemize} diff --git a/devopsAIPromptLog.tex b/devopsAIPromptLog.tex new file mode 100644 index 0000000..e1356de --- /dev/null +++ b/devopsAIPromptLog.tex @@ -0,0 +1,14 @@ +\chapter{AI Prompt Log} +\ChapterLabel{AIPromptLog} +\index{AI prompt log} +\section{How to Use This Appendix} +Use this log when AI assistance materially affects assignment wording, +automation, evidence interpretation, troubleshooting, or feedback. Record +enough context for an instructor or reviewer to understand the input, output, +assumptions, and human corrections. Do not record credentials or personal data. + +\section{Example Record} +Date: \textit{[timestamp]}; Tool and model: \textit{[name]}; Task: +\textit{[requested outcome]}; Inputs: \textit{[sanitized constraints and +evidence]}; Output used: \textit{[summary]}; Human review and corrections: +\textit{[summary]}; Unresolved assumptions: \textit{[list or none]}. diff --git a/devopsAssignment.tex b/devopsAssignment.tex new file mode 100644 index 0000000..dcd2ce3 --- /dev/null +++ b/devopsAssignment.tex @@ -0,0 +1,132 @@ +% SSW 590 DevOps Assignment Template +% Developed by Darian Muresan, Ph.D., with OpenAI Codex and Anthropic Claude Code. +% AI agents: read devopsAIAgentGuide.tex before editing this template. +\documentclass[12pt]{cornell} + +\usepackage[T1]{fontenc} +\usepackage{lmodern} +\usepackage{xspace} +\usepackage{xcolor} +\usepackage{graphicx} +\usepackage{fancyhdr} +\usepackage{amsmath,amssymb} +\usepackage{array} +\usepackage{booktabs} +\usepackage{longtable} +\usepackage{tabularx} +\usepackage{ltablex} +\keepXColumns +\usepackage{enumitem} +\usepackage{listings} +\usepackage{tcolorbox} +\usepackage{makeidx} +\usepackage[colorlinks=true,citecolor=blue,linkcolor=blue,urlcolor=blue]{hyperref} +\usepackage[acronym,toc]{glossaries} + +\makeindex +\makeglossaries +\input{devopsGlossary.tex} + +\definecolor{devopsBlue}{RGB}{31,78,121} +\definecolor{devopsGreen}{RGB}{46,125,50} +\definecolor{devopsRed}{RGB}{183,28,28} +\definecolor{devopsGray}{RGB}{90,90,90} +\definecolor{devopsLightBlue}{RGB}{232,240,247} + +% Replace these values for each assignment. +\newcommand{\AssignmentTitle}{Linux Commands} +\newcommand{\AssignmentNumber}{2} +\newcommand{\DocumentVersion}{1.4} +\newcommand{\DocumentStatus}{} +\newcommand{\CourseNumber}{SSW 590} +\newcommand{\CourseName}{DevOps} +\newcommand{\Instructor}{Maxwell Friedman, Alex Nemirovsky, Sofia Stoeckel, and Magdola Nagy} +\newcommand{\Organization}{Stevens Institute of Technology} +\newcommand{\DocumentDate}{September 16th, 2026} +\newcommand{\DueDate}{} +\newcommand{\VERSION}{Version \DocumentVersion} + +\hypersetup{ + pdftitle={\CourseNumber\ --- Assignment \AssignmentNumber: \AssignmentTitle}, + pdfauthor={\Instructor}, + pdfcreator={Darian Muresan, Ph.D., with OpenAI Codex and Anthropic Claude Code}, + pdfsubject={Reusable DevOps course assignment template}, + pdfkeywords={DevOps, automation, delivery pipeline, infrastructure as code, evidence} +} + +\newcolumntype{Y}{>{\raggedright\arraybackslash}X} +\newcolumntype{L}[1]{>{\raggedright\arraybackslash}p{#1}} +\setlength{\tabcolsep}{4pt} +\renewcommand{\arraystretch}{1.12} +\setlength{\LTpre}{6pt} +\setlength{\LTpost}{6pt} + +% Stable IDs make activity, evidence, and artifact references durable. +\newcommand{\ArtifactLabel}[2]{\phantomsection\label{#1:#2}} +\newcommand{\ArtifactID}[2]{\texttt{#2}\ArtifactLabel{#1}{#2}\index{#1!#2}} +\newcommand{\ArtifactRef}[2]{\hyperref[#1:#2]{\texttt{#2}}} +\newcommand{\ActivityID}[1]{\ArtifactID{Activity}{#1}} +\newcommand{\ActivityRef}[1]{\ArtifactRef{Activity}{#1}} +\newcommand{\EvidenceID}[1]{\ArtifactID{Evidence}{#1}} +\newcommand{\EvidenceRef}[1]{\ArtifactRef{Evidence}{#1}} +\newcommand{\ChapterLabel}[1]{\label{Chapter:#1}} +\newcommand{\ChapterRef}[1]{\hyperref[Chapter:#1]{Chapter~\ref*{Chapter:#1}}} +\newcommand{\StatusPass}{\textbf{\footnotesize\textcolor{devopsGreen}{PASS}}} +\newcommand{\StatusPending}{\textbf{\footnotesize\textcolor{devopsGray}{PENDING}}} +\newcommand{\StatusFail}{\textbf{\footnotesize\textcolor{devopsRed}{FAIL}}} + +\newtcolorbox{devopsNote}[1][]{ + colback=devopsLightBlue, colframe=devopsBlue, boxrule=0.6pt, arc=1mm, title=#1 +} + +\lstset{ + backgroundcolor=\color{white}, basicstyle=\ttfamily\footnotesize, + breaklines=true, frame=single, keywordstyle=\color{blue}, + commentstyle=\color{devopsGreen}, numbers=left, numbersep=6pt, + numberstyle=\tiny\color{devopsGray}, showstringspaces=false, + stringstyle=\color{devopsRed}, tabsize=2 +} + +\changenormalspacing{\singlespacing} +\begin{document} +\pagenumbering{roman} +\singlespacing +\include{prologue} +\include{devopsIntroduction} +\include{devopsExampleAssignment} +\include{linuxCommands} +\include{digitalOceanDocker} +\include{latexDocker} +\include{projectProposal} + +\setcounter{page}{1} +\pagenumbering{arabic} +\pagestyle{fancy} +\fancyhf{} +\renewcommand{\chaptermark}[1]{\markboth{#1}{}} +\lhead{\small Assignment \AssignmentNumber} +\chead{\small\nouppercase{\leftmark}} +\rhead{\small\thepage} +\lfoot{\small\CourseNumber} +\cfoot{\small\copyright\ \Organization} +\rfoot{\small\VERSION} +\renewcommand{\headrulewidth}{0.4pt} +\renewcommand{\footrulewidth}{0.4pt} + +\bibliographystyle{IEEEtran} +\bibliography{devopsReferences} + +\appendix +\include{devopsDocumentGuide} +\include{devopsAIAgentGuide} +\include{devopsAIPromptLog} + +\glsaddall +\printglossaries +\cleardoublepage +\phantomsection +\ChapterLabel{Index} +\addcontentsline{toc}{chapter}{Index} +\markboth{Index}{Index} +\printindex +\end{document} diff --git a/devopsDocumentGuide.tex b/devopsDocumentGuide.tex new file mode 100644 index 0000000..328c3be --- /dev/null +++ b/devopsDocumentGuide.tex @@ -0,0 +1,142 @@ +\chapter{Document Authoring Guide} +\ChapterLabel{DocumentGuide} +\index{LaTeX} +\index{document conventions} +\index{Appendix!Document Authoring Guide} + +\section{How to Use This Appendix} +Use this appendix to maintain the template's file conventions, build process, +and review rules. Update it when the document structure or toolchain changes. + +\section{Template Provenance} +This template was developed by \textbf{Darian Muresan, Ph.D.}, in conjunction +with \textbf{OpenAI Codex} and \textbf{Anthropic Claude Code}. Keep this +attribution distinct from the assignment-specific instructor metadata. + +\section{File Naming and Responsibilities} +Every chapter file shall use the \texttt{devops} prefix, a PascalCase chapter +name, and the \texttt{.tex} suffix. Each such file shall contain one complete +chapter, beginning with \texttt{\string\chapter\{...\}}, and all of its +sections and subsections. Do not split one chapter into section-level +\texttt{.tex} files. For example, all of Chapter~2 is contained in +\path{devopsExampleAssignment.tex}. Do not add requirements or +architecture-design chapters; this template records a DevOps learning activity +and its operational evidence. + +\section{Synonyms and Controlled Terms} +\index{synonyms} +Use one preferred term for each important concept. If an assignment uses +equivalent terms, record them here before release. For example, state whether +``continuous delivery'' refers to \gls{cd} generally or specifically excludes +automatic production deployment. Add important terms to +\texttt{devopsGlossary.tex} and index them where used. + +\section{Building the PDF} +The template requires a LaTeX distribution with \texttt{pdflatex}, +\texttt{bibtex}, \texttt{makeglossaries}, and \texttt{makeindex}. +Install the tools using the platform instructions below, then run one of the +following platform builds. + +\subsection{macOS and Linux Build} +\begin{verbatim} +make -f makefileMacLinux pdf +\end{verbatim} + +\subsection{Windows PowerShell Build} +\begin{verbatim} +.\makefilePowerShell.ps1 -Action pdf +\end{verbatim} +The completed build regenerates references, bibliography, glossary, and index. +Review the log and visually inspect affected PDF pages. Do not edit generated +auxiliary files or the PDF directly. + +\section{Install LaTeX Tools on macOS} +\index{macOS} +\index{MacTeX} +\subsection{Recommended Installation} +Install the current full \href{https://www.tug.org/mactex/}{MacTeX} +distribution. It includes TeX Live, \texttt{pdflatex}, \texttt{bibtex}, +\texttt{latexmk}, \texttt{makeglossaries}, \texttt{makeindex}, and useful +applications such as TeXShop and TeX Live Utility. The full distribution is the +least troublesome choice for this template because it includes the packages +used by the glossary, table, listing, color, and hyperlink features. + +Either download the signed installer from the MacTeX web site and complete the +macOS installation dialog, or, if Homebrew is already installed, run: +\begin{verbatim} +brew install --cask mactex +\end{verbatim} +Close and reopen Terminal after installation. If the TeX commands are not +found, add the MacTeX binary directory to the current shell session: +\begin{verbatim} +export PATH="/Library/TeX/texbin:$PATH" +\end{verbatim} +Do not place this command in a shell profile until it has been verified on the +local computer. + +\subsection{Verification and Compilation} +From the template directory, verify the tools: +\begin{verbatim} +command -v pdflatex bibtex latexmk makeglossaries makeindex +\end{verbatim} +Each command should print a path. Then create the PDF: +\begin{verbatim} +make -f makefileMacLinux pdf +\end{verbatim} +To remove generated intermediate files while keeping the PDF, run: +\begin{verbatim} +make -f makefileMacLinux clean +\end{verbatim} + +\section{Install LaTeX Tools on Windows} +\index{Windows} +\index{MiKTeX} +\subsection{Recommended Installation} +Install the current Basic MiKTeX distribution using the official +\href{https://miktex.org/howto/install-miktex}{MiKTeX Windows installation +guide}. During installation, choose a per-user installation when appropriate +and set missing-package installation to \emph{Ask me first} or \emph{Yes}. +The latter is convenient for a student machine with Internet access; the former +makes each package installation explicit. + +Open MiKTeX Console after installation, apply available updates, and install +the \texttt{latexmk} package if the verification command below cannot find it. +On an organization-managed computer, obtain approval before installing software +or changing execution policy. + +\subsection{Verification and Compilation} +Open a new PowerShell window in the template directory and verify: +\begin{verbatim} +Get-Command pdflatex,bibtex,latexmk,makeglossaries,makeindex +\end{verbatim} +Each command should display a command record. Build the PDF with: +\begin{verbatim} +.\makefilePowerShell.ps1 -Action pdf +\end{verbatim} +If PowerShell blocks the script under a managed execution policy, ask the +system administrator for the approved procedure. Do not bypass institutional +security policy. To remove intermediate build files, run: +\begin{verbatim} +.\makefilePowerShell.ps1 -Action clean +\end{verbatim} + +\section{Common Build Problems} +\begin{tabularx}{\linewidth}{L{3.0cm}Y} +\toprule \textbf{Symptom} & \textbf{Resolution}\\ \midrule +Command not found & Close and reopen the terminal. On macOS, verify the TeX +binary path; on Windows, verify MiKTeX completed installation and is on the user PATH.\\ +Missing LaTeX package & Use MiKTeX Console or its approved on-the-fly package +installation prompt on Windows. On macOS, install the full MacTeX distribution +or use TeX Live Utility to add the missing package.\\ +References or glossary incomplete & Run the supplied platform build instead of +a single \texttt{pdflatex} command; it runs BibTeX, the glossary tool, and the +index tool in the required order.\\ +Script is blocked & Follow the institution's approved PowerShell policy or run +the documented build commands with an approved administrator.\\ \bottomrule +\end{tabularx} + +\section{Authoring and Review Rules} +Replace bracketed placeholders with assignment facts. Keep operational examples +safe, bounded, and free of credentials. Link activities to evidence, retain +history, and state unknowns or instructor decisions explicitly. Rebuild after +structural, cross-reference, table, glossary, or index changes. diff --git a/devopsDocumentHistory.tex b/devopsDocumentHistory.tex new file mode 100644 index 0000000..b5073a3 --- /dev/null +++ b/devopsDocumentHistory.tex @@ -0,0 +1,22 @@ +\chapter*{Document History} +\addcontentsline{toc}{chapter}{Document History} +\index{document history} +\section*{How to Use This Chapter} +Add the newest approved change at the top. Retain every approved entry and +link each entry to the changed chapter, table, figure, or controlled artifact. + +\begin{tabularx}{\linewidth}{L{3.1cm}L{2.2cm}YL{2.0cm}} +\caption{Document Update History\label{Table:DocumentHistory}}\\ +\toprule \textbf{Date / Version} & \textbf{Author Initials} & \textbf{Change} & \textbf{Changed At}\\ \midrule +\endfirsthead +\multicolumn{4}{l}{\small\itshape Document Update History (continued)}\\ +\toprule \textbf{Date / Version} & \textbf{Author Initials} & \textbf{Change} & \textbf{Changed At}\\ \midrule +\endhead \bottomrule \endlastfoot +September 24, 2026 / 1.5 & MF, AN, SS, MN & Created the Digital Ocean Docker Deployment, LaTeX, and Project Proposal chapters. & \ChapterRef{DigitalOceanDocker}, \ChapterRef{LatexDocker}, \ChapterRef{ProjectProposal}\\ +September 16, 2026 / 1.4 & MF, AN, SS, MN & Created the Linux Commands chapter at \texttt{linuxCommands.tex}. & \ChapterRef{LinuxCommands}\\ +September 2, 2026 / 1.3 & DDM, CDX & Established the one-file-per-chapter convention, added it to the AI Agent Usage Guide, and consolidated the complete example assignment chapter into \texttt{devopsExampleAssignment.tex}. & \ChapterRef{ExampleAssignment}, \ChapterRef{AIAgentGuide}, \ChapterRef{DocumentGuide}\\ +September 2, 2026 / 1.2 & DDM, CDX & Added macOS MacTeX and Windows MiKTeX installation, verification, compilation, cleanup, and troubleshooting instructions to the Document Authoring Guide appendix. & \ChapterRef{DocumentGuide}\\ +September 2, 2026 / 1.1 & DDM, CDX & Reorganized the example assignment as one chapter with activity, workflow, evidence, retrospective, and submission sections so each homework can follow the same chapter pattern. & \ChapterRef{ExampleAssignment}\\ +September 2, 2026 / 1.0 & DDM, CDX & Created the reusable SSW 590 DevOps assignment template from the architecture template infrastructure; replaced requirements and design chapters with activity, workflow, evidence, retrospective, and submission chapters. & \ChapterRef{Introduction}, \ChapterRef{ExampleAssignment}, \ChapterRef{AIAgentGuide}\\ +\textit{[date / version]} & \textit{[initials]} & \textit{[approved change and rationale]} & \textit{[link]}\\ +\end{tabularx} diff --git a/devopsExampleAssignment.tex b/devopsExampleAssignment.tex new file mode 100644 index 0000000..1180e2f --- /dev/null +++ b/devopsExampleAssignment.tex @@ -0,0 +1,126 @@ +\chapter{Example Assignment} +\ChapterLabel{ExampleAssignment} +\index{activity brief} +\index{workflow} +\index{automation} +\index{infrastructure as code} +\index{evidence} +\index{observability} +\index{rollback} +\index{retrospective} +\index{continuous improvement} +\index{submission} +\index{cleanup} + +\section{Activity Brief} +\subsection{Scenario} +Describe the operational scenario and why it matters. Use a bounded, +non-production system. \textit{Example: A team must deploy a small service +reliably to a remote Linux host and recover from a failed release.} + +\subsection{Activities} +Assign stable IDs to each assessed activity. Add rows as needed. +\begin{tabularx}{\linewidth}{L{2.1cm}L{3.1cm}Y} +\caption{Activity Register\label{Table:ActivityRegister}}\\ +\toprule \textbf{ID} & \textbf{Activity} & \textbf{Completion criterion}\\ \midrule +\ActivityID{ACT-01} & \textit{[Prepare environment]} & \textit{[repeatable environment baseline is present]}\\ +\ActivityID{ACT-02} & \textit{[Automate workflow]} & \textit{[workflow runs from documented inputs]}\\ +\ActivityID{ACT-03} & \textit{[Observe and recover]} & \textit{[evidence shows monitoring and recovery]}\\ \bottomrule +\end{tabularx} + +\subsection{Success Criteria} +State observable outcomes, not implementation prescriptions. Include security, +cost, cleanup, and reproducibility criteria where applicable. + +\subsection{Assessment Rubric} +\begin{tabularx}{\linewidth}{L{3.2cm}L{2.0cm}Y} +\toprule \textbf{Criterion} & \textbf{Weight} & \textbf{Evidence expected}\\ \midrule +Reproducible workflow & \textit{[points]} & \textit{[automation and clean-run proof]}\\ +Operational quality & \textit{[points]} & \textit{[observability, rollback, security]}\\ +Evidence and explanation & \textit{[points]} & \textit{[commands, outputs, rationale]}\\ +Reflection & \textit{[points]} & \textit{[failure analysis and improvement]}\\ \bottomrule +\end{tabularx} + +\section{Workflow and Implementation} +\subsection{Environment Baseline} +Specify the authorized environment, prerequisites, access model, versioned +inputs, and teardown procedure. Record commands in a repository script or +infrastructure-as-code definition; do not rely on a sequence of undocumented +console clicks. + +\subsection{Procedure} +For each activity, state the goal, input, command or automation entry point, +expected result, and rollback or cleanup action. Link the corresponding +activity identifier and evidence identifier. + +\begin{lstlisting}[language=bash,caption={Replace with a safe, repeatable workflow entry point.}] +# ./scripts/provision.sh --environment sandbox +# ./scripts/deploy.sh --version +# ./scripts/destroy.sh --environment sandbox +\end{lstlisting} + +\subsection{Operational Controls} +Describe least-privilege access, secret handling, logging, monitoring, change +control, budget guardrails, backup or rollback, and resource cleanup. A secret +shall be referenced by its approved storage location, never pasted into this +document or committed to the repository. + +\subsection{Failure Exercise} +Define one safe failure or degradation scenario. State the trigger, expected +signal, diagnosis path, recovery action, and evidence required. Never direct +students to disrupt shared or production infrastructure. + +\section{Evidence Register} +\subsection{How to Use This Section} +Evidence demonstrates an actual execution; an expected result is not evidence. +Use sanitized command output, logs, screenshots, links to versioned files, or +recorded metrics. Redact secrets and personal information. + +\begin{tabularx}{\linewidth}{L{1.7cm}L{2.2cm}L{2.6cm}Y} +\caption{Evidence Register\label{Table:EvidenceRegister}}\\ +\toprule \textbf{ID} & \textbf{Activity} & \textbf{Evidence type} & \textbf{Location and interpretation}\\ \midrule +\EvidenceID{EVD-01} & \ActivityRef{ACT-01} & \textit{[log / script / image]} & \textit{[repository path or sanitized URL; what it demonstrates]}\\ +\EvidenceID{EVD-02} & \ActivityRef{ACT-02} & \textit{[pipeline output]} & \textit{[location; result and relevant timestamp]}\\ +\EvidenceID{EVD-03} & \ActivityRef{ACT-03} & \textit{[monitoring / recovery output]} & \textit{[location; failure signal and recovery result]}\\ \bottomrule +\end{tabularx} + +\subsection{Evidence Quality Checks} +Evidence should identify the executed version, environment, time, command or +automation entry point, outcome, and any deviation from the expected result. +State failures plainly; they are valuable inputs to the retrospective. + +\section{Retrospective} +\subsection{Outcome} +Summarize what happened, including completed work, gaps, and unexpected +behavior. Distinguish facts from interpretation. + +\subsection{Flow and Feedback} +Identify queues, handoffs, manual steps, slow feedback, and sources of rework. +Explain which changes improved delivery flow or made failures visible sooner. +This emphasis on flow, feedback, and continual learning is consistent with the +DevOps framing introduced in \cite{PhoenixProject}. + +\subsection{Improvement Experiments} +Propose one or more small, testable improvements. State the hypothesis, change, +measurement, expected result, and risk. Do not represent a proposal as an +approved production change. + +\subsection{Team Contributions} +For team assignments, concisely identify each member's meaningful contribution +and any collaboration constraints. + +\section{Submission and Cleanup} +\subsection{Submission Checklist} +\begin{itemize} +\item Versioned automation, configuration, and runbook are committed. +\item Evidence links resolve and contain no secrets or personal data. +\item The retrospective is complete and distinguishes results from proposals. +\item Remote resources have been destroyed or explicitly transferred as directed. +\item The repository identifies the final commit or release tag. +\end{itemize} + +\subsection{Academic Integrity and Responsible Use} +Follow the course policy for collaboration and AI assistance. Cite external +code, tutorials, and AI-generated material as required by the instructor. +Students remain responsible for understanding, testing, and explaining all +submitted work. diff --git a/devopsGlossary.tex b/devopsGlossary.tex new file mode 100644 index 0000000..186607f --- /dev/null +++ b/devopsGlossary.tex @@ -0,0 +1,13 @@ +\newacronym{ai}{AI}{artificial intelligence} +\newacronym{ci}{CI}{continuous integration} +\newacronym{cd}{CD}{continuous delivery or continuous deployment} +\newacronym{iac}{IaC}{infrastructure as code} +\newacronym{slo}{SLO}{service-level objective} +\newglossaryentry{automation}{name={automation},description={A repeatable, version-controlled procedure executed by software rather than undocumented manual steps}} +\newglossaryentry{deployment}{name={deployment},description={The controlled delivery of a versioned change to an environment}} +\newglossaryentry{evidence}{name={evidence},description={A retained record of an actual execution, observation, or review}} +\newglossaryentry{observability}{name={observability},description={The ability to infer system behavior from signals such as logs, metrics, traces, and health checks}} +\newglossaryentry{pipeline}{name={pipeline},description={An automated sequence that builds, tests, packages, and/or deploys a change}} +\newglossaryentry{rollback}{name={rollback},description={A controlled return to a known acceptable version or state after a failed or harmful change}} +\newglossaryentry{runbook}{name={runbook},description={A documented operational procedure for a repeatable task or incident response}} +\newglossaryentry{synonyms}{name={synonyms},description={Equivalent terms used in this assignment; record preferred terms to avoid ambiguity in instructions and evidence}} diff --git a/devopsIntroduction.tex b/devopsIntroduction.tex new file mode 100644 index 0000000..2d3eddd --- /dev/null +++ b/devopsIntroduction.tex @@ -0,0 +1,47 @@ +\chapter{Introduction} +\ChapterLabel{Introduction} +\index{introduction} +\index{DevOps} + +\section{How to Use This Assignment} +Replace bracketed text with approved assignment facts. Delete instructional +examples before release, but retain the stable identifiers, history, glossary, +index, appendices, and evidence structure. This document is an assignment +brief and operational record, not a requirements or software-design document. + +\section{Purpose and Learning Objectives} +State the DevOps capability students will practice and the observable learning +outcomes. \textit{Example: Students will provision a minimal Linux service, +automate its deployment, collect operational evidence, and demonstrate a safe +rollback.} + +\section{Scope and Constraints} +State the permitted cloud or local environment, team size, required tools, +budget limits, source-control repository, timebox, and prohibited actions. +Do not include credentials, access tokens, student records, or production data. + +\section{Deliverables and Due Date} +\begin{tabularx}{\linewidth}{L{3.2cm}Y} +\toprule \textbf{Item} & \textbf{Expectation}\\ \midrule +Due date & \DueDate\\ +Repository & \textit{[repository URL or LMS location]}\\ +Required deliverables & \textit{[automation, runbook, evidence, reflection]}\\ +Team policy & \textit{[individual or team; contribution expectations]}\\ \bottomrule +\end{tabularx} + +\section{Using This Template with AI Agents} +\index{AI agent!DevOps workflow} +AI may assist with explanation, drafting, troubleshooting, and reviewing +automation. It does not replace student understanding or authorize an agent to +operate accounts, approve work, invent results, or receive secrets. Before +editing, an AI agent shall read \texttt{devopsAIAgentGuide.tex}, load only the +relevant assignment files, identify assumptions, and preserve evidence +boundaries. Record material AI assistance in \ChapterRef{AIPromptLog}. + +\begin{verbatim} +Read devopsAIAgentGuide.tex first. For this SSW 590 assignment, identify the +requested task and read only the listed sources. Use supplied evidence only; +do not invent commands, deployment results, approvals, credentials, or costs. +Preserve stable IDs and history. Make the smallest appropriate change, build +the PDF, and report assumptions, risks, and actions requiring human approval. +\end{verbatim} diff --git a/devopsReferences.bib b/devopsReferences.bib new file mode 100644 index 0000000..59f00cb --- /dev/null +++ b/devopsReferences.bib @@ -0,0 +1,6 @@ +@book{PhoenixProject, + author = {Kim, Gene and Behr, Kevin and Spafford, George}, + title = {The Phoenix Project: A Novel about IT, DevOps, and Helping Your Business Win}, + publisher = {IT Revolution Press}, + year = {2018} +} diff --git a/digitalOceanDocker.tex b/digitalOceanDocker.tex new file mode 100644 index 0000000..c6b9fea --- /dev/null +++ b/digitalOceanDocker.tex @@ -0,0 +1,3 @@ +\chapter{Digital Ocean Docker Deployment} +\ChapterLabel{DigitalOceanDocker} + diff --git a/latexDocker.tex b/latexDocker.tex new file mode 100644 index 0000000..75c67f5 --- /dev/null +++ b/latexDocker.tex @@ -0,0 +1,3 @@ +\chapter{LaTeX Docker} +\ChapterLabel{LatexDocker} + diff --git a/linuxCommands.tex b/linuxCommands.tex new file mode 100644 index 0000000..8a37759 --- /dev/null +++ b/linuxCommands.tex @@ -0,0 +1,338 @@ +\chapter{Linux Commands} +\ChapterLabel{LinuxCommands} + +\begin{figure}[htbp] + \centering + \includegraphics[width=1\textwidth]{terminal.png} + \caption{Linux terminal screenshot of the bash commands ran in Step 2.} + \label{fig:linux_terminal} +\end{figure} + +\section{Navigation and File Ops} + + +1. paris@paris-Precision-3581:~/lx-test + +\begin{figure} + \centering + \includegraphics[width=1\linewidth]{linux/image0.png} + \caption{All entries in ~/lx-test.} + \label{fig:img2} +\end{figure} + +\begin{figure} + \centering + \includegraphics[width=1\linewidth]{linux/image1.png} + \caption{Copying txt to tmp.} + \label{fig:img3} +\end{figure} + +\begin{figure}[hbt!] + \centering + \includegraphics[width=1\linewidth]{linux/image2.png} + \caption{old.txt moved into archive/.} + \label{fig:img4} +\end{figure} + +\begin{figure}[hbt!] + \centering + \includegraphics[width=1\linewidth]{linux/image3.png} + \caption{New empty file notes.md created.} + \label{fig:img5} +\end{figure} + +\begin{figure}[hbt!] + \centering + \includegraphics[width=1\linewidth]{linux/image4.png} + \caption{Disk usage for the src directory.} + \label{fig:img6} +\end{figure} + +\newpage +\section{Viewing and Searching} + + +\begin{figure}[hbt!] + \centering + \includegraphics[width=1\linewidth]{linux/image6.png} + \caption{Line numbers printed in sys.log.} + \label{fig:img7} +\end{figure} + +\begin{figure}[hbt!] + \centering + \includegraphics[width=1\linewidth]{linux/image7.png} + \caption{sys.log lines filtered by ERROR.} + \label{fig:img8} +\end{figure} + +\begin{figure}[hbt!] + \centering + \includegraphics[width=1\linewidth]{linux/image8.png} + \caption{Distinctive words in words.txt counted.} + \label{fig:img9} +\end{figure} + +\begin{figure}[hbt!] + \centering + \includegraphics[width=1\linewidth]{linux/image9.png} + \caption{Lines starting with G in words.txt shown.} + \label{fig:img10} +\end{figure} + +\begin{figure}[hbt!] + \centering + \includegraphics[width=1\linewidth]{linux/image10.png} + \caption{First two lines of people.csv displayed.} + \label{fig:img11} +\end{figure} + +\begin{figure}[hbt!] + \centering + \includegraphics[width=1\linewidth]{linux/image11.png} + \caption{Last three lines of sys.log shown.} + \label{fig:img12} +\end{figure} + +\newpage +\section{Text Processing} + + +\begin{figure}[hbt!] + \centering + \includegraphics[width=1\linewidth]{linux/image12.png} + \caption{Name column of people.csv printed.} + \label{fig:img13} +\end{figure} + +\begin{figure}[hbt!] + \centering + \includegraphics[width=1\linewidth]{linux/image13.png} + \caption{words.txt sorted case-insensitively without duplicates.} + \label{fig:img14} +\end{figure} + +\begin{figure}[hbt!] + \centering + \includegraphics[width=1\linewidth]{linux/image14.png} + \label{fig:img15} +\end{figure} +\begin{figure}[hbt!] + \centering + \includegraphics[width=1\linewidth]{linux/imaging.png} + \caption{"three" replaced with 3 in src.txt with backups.} + \label{fig:placeholder} +\end{figure} + +\begin{figure}[hbt!] + \centering + \includegraphics[width=1\linewidth]{linux/image15.png} + \caption{Lines, words, and bytes printed for every *.txt file in src.} + \label{fig:img16} +\end{figure} + +\newpage +\section{Permissions and Ownership} + + +\begin{figure}[hbt!] + \centering + \includegraphics[width=1\linewidth]{linux/image16.png} + \caption{tmp/ made only read/write/searchable by the owner.} + \label{fig:img17} +\end{figure} + +\begin{figure}[hbt!] + \centering + \includegraphics[width=1\linewidth]{linux/image17.png} + \caption{src/lib given group execute permission recursively.} + \label{fig:img18} +\end{figure} + +\begin{figure}[hbt!] + \centering + \includegraphics[width=1\linewidth]{linux/image18.png} + \caption{Numeric permissions of src/file2.txt shown.} + \label{fig:img19} +\end{figure} + +\begin{figure}[hbt!] + \centering + \includegraphics[width=1\linewidth]{linux/image19.png} + \caption{notes.md made append-nly for the owner.} + \label{fig:img20} +\end{figure} + +\newpage +\section{Links and Find} + + +\begin{figure}[hbt!] + \centering + \includegraphics[width=1\linewidth]{linux/image20.png} + \caption{link-to-file1's target path.} + \label{fig:img21} +\end{figure} + +\begin{figure}[hbt!] + \centering + \includegraphics[width=1\linewidth]{linux/image21.png} + \caption{All regular files over 40 KiB under the current tree.} + \label{fig:img22} +\end{figure} + +\begin{figure}[hbt!] + \centering + \includegraphics[width=1\linewidth]{linux/image22.png} + \caption{Files modified in the last 10 minutes under tmp/.} + \label{fig:img23} +\end{figure} + +\newpage +\section{Processes and Job Control} + + +\begin{figure}[hbt!] + \centering + \includegraphics[width=1\linewidth]{linux/image23.png} + \label{fig:img24} +\end{figure} +\begin{figure} + \centering + \includegraphics[width=1\linewidth]{linux/imagest.png} + \label{fig:placeholder} +\end{figure} +\begin{figure} + \centering + \includegraphics[width=1\linewidth]{linux/imageringest.png} + \caption{Processes shown in tree view.} + \label{fig:placeholder} +\end{figure} + +\begin{figure}[hbt!] + \centering + \includegraphics[width=1\linewidth]{linux/image24.png} + \caption{sleep 120 started and its PID.} + \label{fig:img25} +\end{figure} + +\begin{figure}[hbt!] + \centering + \includegraphics[width=1\linewidth]{linux/image25.png} + \caption{TERM signal sent to all sleep processes.} + \label{fig:img26} +\end{figure} + +\begin{figure}[hbt!] + \centering + \includegraphics[width=1\linewidth]{linux/image26.png} + \caption{Top 5 processes by memory usage shown.} + \label{fig:img27} +\end{figure} + +\newpage +\section{Archiving and Compression} + + +\begin{figure}[hbt!] + \centering + \includegraphics[width=1\linewidth]{linux/image27.png} + \caption{src.tgz created from src/.} + \label{fig:img28} +\end{figure} + +\begin{figure}[hbt!] + \centering + \includegraphics[width=1\linewidth]{linux/image28.png} + \caption{Contents of src.tgz listed.} + \label{fig:img29} +\end{figure} + +\begin{figure}[hbt!] + \centering + \includegraphics[width=1\linewidth]{linux/image29.png} + \caption{file2.txt extracted from src.tgz into tmp/.} + \label{fig:img30} +\end{figure} + +\newpage +\section{Networking and System Info} + + +\begin{figure}[hbt!] + \centering + \includegraphics[width=1\linewidth]{linux/image30.png} + \caption{All listening TCP sockets with PIDs shown.} + \label{fig:img31} +\end{figure} + +\begin{figure}[hbt!] + \centering + \includegraphics[width=1\linewidth]{linux/image31.png} + \caption{Default route concisely printed.} + \label{fig:img32} +\end{figure} + +\begin{figure}[hbt!] + \centering + \includegraphics[width=1\linewidth]{linux/image32.png} + \caption{Kernel name, release, and machine architecture displayed.} + \label{fig:img33} +\end{figure} + +\begin{figure}[hbt!] + \centering + \includegraphics[width=1\linewidth]{linux/image33.png} + \caption{Last five successful logins shown.} + \label{fig:img34} +\end{figure} + +\newpage +\section{Package and Services (Ubuntu)} + + +\begin{figure}[hbt!] + \centering + \includegraphics[width=1\linewidth]{linux/image34.png} + \caption{Installed version of the coreutils package shown.} + \label{fig:img35} +\end{figure} + +\begin{figure}[hbt!] + \centering + \includegraphics[width=1\linewidth]{linux/image35.png} + \caption{Available packages with names containing "ripgrep".} + \label{fig:img36} +\end{figure} + +\begin{figure}[hbt!] + \centering + \includegraphics[width=1\linewidth]{linux/image36.png} + \caption{Status line of cron service.} + \label{fig:img37} +\end{figure} + +\newpage +\section{Bash and Scripting} + + +\begin{figure}[hbt!] + \centering + \includegraphics[width=1\linewidth]{linux/image37.png} + \caption{One-liner that loops over *.txt in src.} + \label{fig:img38} +\end{figure} + +\begin{figure}[hbt!] + \centering + \includegraphics[width=1\linewidth]{linux/image38.png} + \caption{Command that exports csv rows where dept == "CS" to cs.txt.} + \label{fig:img39} +\end{figure} + +\begin{figure}[hbt!] + \centering + \includegraphics[width=1\linewidth]{linux/image39.png} + \caption{Variable X with value 42 created, printed, and deleted.} + \label{fig:img40} +\end{figure} \ No newline at end of file diff --git a/projectProposal.tex b/projectProposal.tex new file mode 100644 index 0000000..a25330d --- /dev/null +++ b/projectProposal.tex @@ -0,0 +1,3 @@ +\chapter{Project Proposal} +\ChapterLabel{ProjectProposal} + diff --git a/prologue.tex b/prologue.tex new file mode 100644 index 0000000..a3d604e --- /dev/null +++ b/prologue.tex @@ -0,0 +1,25 @@ +\title{\CourseNumber\ --- \CourseName\\[0.5em]\large Assignment \AssignmentNumber: \AssignmentTitle\\[1.5em]\normalsize\VERSION\\\DocumentStatus} +\author{\Instructor\\\Organization} +\conferraldate{}{\DocumentDate} +\copyrightholder{\Organization} +\copyrightyear{2026} +\maketitle +\makecopyright + +\cleardoublepage +\phantomsection +\chapter*{Template Attribution} +\ChapterLabel{TemplateAttribution} +\addcontentsline{toc}{chapter}{Template Attribution} +\markboth{Template Attribution}{Template Attribution} +\index{template attribution} +\index{Muresan, Darian} +This DevOps assignment template was developed by \textbf{Darian Muresan, Ph.D.}, +in conjunction with \textbf{OpenAI Codex} and \textbf{Anthropic Claude Code}. + +\clearpage +\begin{abstract}\input{abstract.tex}\end{abstract} +\input{devopsDocumentHistory.tex} +\contentspage +\tablelistpage +\figurelistpage diff --git a/terminal.png b/terminal.png new file mode 100644 index 0000000..c7aeebe Binary files /dev/null and b/terminal.png differ