# Business rules — wiki (SO Wiki System)

Evidence date: 2026-09-28.

Source: `git@bitbucket.org:overdrive/wiki.git`, `master` at `bb3c49b` (2019-05-02).

No business-rules document exists in the source repository. Rules below are taken from code, HTML, and deploy scripts. Anything marked **Inferred** is a conclusion from that evidence, not a written policy. The committed private key is not reproduced.

## Identity and access

### BR-001 — Login does not authenticate

**Inferred** from **Implemented** markup.

The login form requires a non-empty password and a value the browser accepts as an email. It does not compare those values to an account store. The inputs have no `name`, so the values are not transmitted. Submit navigates to `views/dashboard/index.html`.

There is no session cookie, token, or server check on the dashboard.

Evidence: `index.html`.

### BR-002 — Forgotten password and registration are not processes

**Implemented** links only.

"Forgot password?" is an anchor to `#`. "Create an account" points at `views/register.html`, which is not in the repository. No rule defines eligibility, approval, or password policy for a new account.

The theme page `views/template/register.html` is a demo form. It is not the target of the root login link, and no script in this repository posts it to an account service.

### BR-003 — The person named in the shell is fixed text

**Implemented.**

`views/dashboard/index.html` always shows "Jaco Brits" and "Software Director". That text does not change after login.

**Unknown / Requires Confirmation:** whether this was intended as the product's only operator.

### BR-004 — Roles are named and not applied

**Planned** in a comment. Not an enforced rule.

`controller/core.js` comments list:

| Number | Name in the comment | Behaviour |
|---|---|---|
| 1 | Developer (debug) | Commented code would set `debug = true` and then set `role = 2` |
| 2 | Admin | Would be used as the nav-file suffix |
| 3 | Manager | Same |
| 4 | No name written | Same pattern, if `userRole` were 4 |

`userRole` is not defined. The branch is commented out. No page checks a role before showing a menu item.

**Inferred** from the commented Developer branch: a Developer would have been shown the Admin navigation (`role = 2`) with a debug flag. That inference applies only to the comment, not to running behaviour.

### BR-005 — Logout is a link, not a session end

**Implemented.**

Three controls in the shell:

| Control | Target | Result |
|---|---|---|
| Top bar "Log out" | `views/template/login.html` | Theme login page |
| Side menu "Logout" | `views/index.html` | File not in the repository |
| Profile menu "Logout" | `views/dashboard/login.html` | File not in the repository |

No script clears storage. `logOut()` is referenced in `controller/core.js` and is not defined. The script also does not parse, so that call is not reached.

## Navigation and content

### BR-006 — Wiki opens the theme blog

**Implemented.**

The only Wiki menu item loads `views/template/blog.html`. It does not load `views/wiki/blog.html`.

### BR-007 — Article cards are fixed content

**Implemented.**

Titles, authors, dates, tags, comment counts, and view counts on `views/wiki/blog.html` and `views/template/blog.html` are written in the HTML. Examples of the static facts on the cards:

- "One morning, when Gregor Samsa", author Adam Novak, 28th Oct 2015, tags Model and Publishing, 56 comments, 144 views.
- Further cards use the same pattern (Mike Smith, Anthony Dvorak, and others).

There is no rule that computes views or comments. There is no permission rule for who may edit an article, because editing is not implemented.

### BR-008 — Search does not query a wiki

**Implemented.**

The shell search form submits to `search_results.html` next to the dashboard file. That file is absent. The theme search page is a static demo. No code reads the `top-search` field and filters articles.

### BR-009 — Department dashboards do not enforce a department

**Implemented** labels. **Inferred** that they are not access scopes, because every page is a static file with no check.

Labels on the copied dashboards are Software, Technical, Support, HR, and Finance. The shell that links to four of them still calls them Dashboard v.1–v.5. Any visitor who can open the file can open any of them.

**Unknown / Requires Confirmation:** whether those names were meant as business areas.

### BR-010 — Storage and message counts are display text

**Implemented.**

The shell footer states "10GB of 250GB Free." The envelope badge states 16. The bell badge states 8. Nothing in the repository measures disk use or an inbox.

### BR-011 — Page fragments would load by path concatenation

**Implemented** source, not running behaviour. The script is not valid JavaScript.

If `pageContent(view, page)` ran, the browser would request `views/<view>/<page>.html` relative to the dashboard page's `../../views/` prefix. There is no allow-list. The only call passes the view `blog` and omits the page.

A click on `.button` with an `action` other than `updateProfile` or `logout` would call `pageContent('dashboard', 'index')`. `updateProfile` has an empty body. No validation of `eltarget` or `url` is written, and those attributes are unread.

## Deployment rules encoded in scripts

### BR-012 — The whole tree is the revision

**Implemented.**

`bitbucket-pipelines_org.yml` runs `zip -r /tmp/artifact.zip *` from the repository root. `appspec.yml` copies source `/` to `/var/www/html/`. That includes HTML, assets, Python deploy scripts, and `SOawsCodeDeploy.pem`.

**Inferred:** a successful deploy would make the private key file available under the web root. Whether directory listing or the file's mode would expose it depends on `httpd` configuration, which is not in the repository.

### BR-013 — Production and development use different CodeDeploy names

**Implemented** in the two Python scripts.

| Script | Application name env | Deployment group env | S3 bucket env | Config env |
|---|---|---|---|---|
| `codedeploy_deploy.py` | `APPLICATION_NAME` | `DEPLOYMENT_GROUP_NAME` | `S3_BUCKET` | `DEPLOYMENT_CONFIG` |
| `codedeploy_deploy_develop.py` | `APPLICATION_NAME_DEV` | `DEPLOYMENT_GROUP_NAME_DEV` | `S3_BUCKET` | `DEPLOYMENT_CONFIG` |

The pipeline file attaches the first script to branch `master` and the second to branch `develop`. Only `master` exists. The pipeline file's name is not `bitbucket-pipelines.yml`.

The S3 key is `<application name>/<YYYYmmddHHMMSS>-bitbucket_builds.zip`.

`ignoreApplicationStopFailures` is true on both `create_deployment` calls.

### BR-014 — The host is expected to install Apache with yum

**Implemented.**

`scripts/install_dependencies` runs `yum install -y httpd` as root. `scripts/start_server` runs `service httpd start` as root. No virtual host, no TLS, and no document-root override are in the repository. The appspec destination `/var/www/html/` matches the usual `httpd` document root on Amazon Linux. That match is **Inferred**.

`scripts/stop_server` is registered as `ApplicationStop`. The assignment is written `isExistApp = \`pgrep httpd\`` with spaces around `=`. In bash that does not set the variable. The following test of `$isExistApp` therefore does not see the `pgrep` result, and `service httpd stop` is not run on that path.

`start_server` is registered under `BeforeInstall`, which CodeDeploy runs before the file copy. `httpd` is started before the new files are installed. There is no `ApplicationStart` hook to start it again after the copy.

Hook timeout is 300 seconds. `runas` is `root`.

### BR-015 — Deploy failure stops the script

**Implemented.**

If the S3 upload returns false, or `create_deployment` throws, or the polled status is `Failed` or `Stopped`, the Python script prints the error and `sys.exit(1)`. Statuses `InProgress`, `Queued`, and `Created` keep the loop going. There is no sleep in the loop body (`sleep` is imported and unused), so the poll is a tight loop until the deployment leaves those states or the client throws.

A missing environment variable raises in Python when the script builds `BUCKET_KEY` (`os.getenv(...) + '/' + ...` when the name is unset). That is an uncaught exception, not the printed ClientError path.

## Rules that are not in this repository

- Who may publish a wiki page.
- Article review, retention, or deletion.
- Password composition, lockout, or reset.
- How services and projects mentioned on the login screen ("manage your services , projects") are created or billed.
- Which company entities the department labels refer to.
- A data-retention or privacy rule. No personal-data store exists here. The shell does embed one person's name and job title as HTML.

## Conflicts that need a decision

The README calls this a wiki. The running pages are a static admin theme, and login does not establish a user. Those are not treated here as a business rule that articles must be editable. If that was the intent, it is not what `master` does.
