Start user-docs/ with the architecture page, and design the site around it - #104
Merged
Conversation
…nd it
D-10 chose plain Markdown with the renderer deferred. This tests that choice
against the hardest page in the plan rather than the easiest, and it holds:
CommonMark plus tables carried the whole thing, and the requirement list is
Markdown with tables, static assets, and a theme whose image CSS is one rule
away from correct. Nothing here argues for a framework.
Two bugs only appear once a diagram is a standalone .svg rather than inline
HTML, and both fail silently as a broken image:
- HTML named entities are undefined in XML. A standalone .svg is parsed as
XML, so — makes the file fail to render entirely. All numeric now.
- Angle brackets in the SVG's CSS, even inside a comment, parse as tags.
The diagrams were re-authored at a 900px viewBox with larger type and zones
stacked vertically instead of side by side. Carried over at 1160px they
scaled to 7.5px body text in a docs column, which is unreadable; at 900px
they hold above 10px down to an 820px viewport. That withdraws the wide-layout
variant this design first proposed for explainer pages -- it was compensating
for over-wide diagrams, and the site keeps one layout instead of two.
Both defects found in the re-authored set were geometric and invisible in
review: a 4px card overlap and a text run escaping its card. Checking every
getBBox() against its containing rectangle found both, and that check is
written into user-docs/README.md as a convention.
The IA maps 34 pages across 8 sections against what already exists -- 12 are
a porting job, 5 are scattered, 17 need writing. It also proposes one
amendment to D-10, for the decisions log: user-docs owns evaluate as well as
use, because a reviewer approving TOPS for an AWS org reads before anything
is installed and will not read a README to do it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The IA said three archetypes and left it there, which is not enough to keep 17 pages written by different people months apart from diverging. Each archetype is now a copyable skeleton with the guidance inline as comments that do not render, so the rule is next to the thing it governs rather than in a document nobody rereads. The seven voice rules are the ones that are checkable rather than tasteful. Two earn their place from work already done here: "never claim more than the code does" comes from the child IAM role not being read-only, which is the kind of overstatement a reviewer catches and then stops trusting the rest of the site over -- so every explainer carries a "What we do not claim" section. "Symptom before cause" is because troubleshooting is reached by searching an error message, not by browsing a subsystem. The writing order is dependency order, not importance order. Reading a finding precedes resolving one, because resolution is meaningless to someone who cannot yet interpret severity. Deploying the site waits until four real pages exist, since a live site with one page invites filler. Also fixes three dead links the architecture page shipped with -- it pointed at pages the IA plans but nobody has written. They now point at the repository files that exist today, and a link check is written into the conventions so the next page cannot repeat it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…es publicly A public repo with three open security issues and a reviewer-facing architecture page had nowhere to report a vulnerability. README's Support section said "open an issue", which for a vulnerability is the one thing you do not want someone to do, so that now carries a carve-out. Reporting is GitHub private advisories first, security@teemops.com as a fallback for people who will not use GitHub. Commitments are deliberately modest -- acknowledge in 5 working days, assess in 10 -- because a missed public promise costs more credibility than a slow one, and this is a small team. Two sections do more work than the boilerplate. "What we are most worried about" ranks the failure classes, led by cross-organisation data access, because telling researchers where to look is the point of having a policy. "Already known" lists #100, #101 and #102 with honest impact, so nobody spends a weekend rediscovering the open SNS topic and nobody reports it as though it were news. Scope draws the line self-hosted products have to draw: an operator with a shell on their own host is not a vulnerability, and neither is running with APP_DEBUG on a public address. BLOCKED ON TWO THINGS before this is true rather than aspirational: GitHub private vulnerability reporting is disabled on the repo and must be turned on, and security@teemops.com does not exist yet. Until both land the policy names channels that do not answer. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The architecture page summarised the permissions honestly but at a level a reviewer will not accept on its own. This is the page they get pointed to next: 2 managed policies, 21 inline ones, which 3 are resource-scoped and which 18 carry Resource "*". Two things came out of reading the template properly rather than summarising it again. The write permissions are not used by anything. TOPS instantiates only STS, SNS and SQS clients; there is no SecurityHub, GuardDuty, Macie, Inspector, Config or CloudTrail code in the repository at all, and every one of the 36 operations declared across rules/tasks/*/tasks.json is list, get or describe. So the role asks for write access across eight services on behalf of features that do not exist. The page says exactly that, and shows how to strip them. And s3:ListAllMyBuckets in TopsS3Bucket can never authorise -- it does not support resource-level permissions and the statement scopes it to arn:aws:s3:::tops-config-*. Inert rather than dangerous, but a reviewer would find it, so we say it first. The architecture page said the write half "exists for the operational features that manage AWS security services on your behalf", which implied those features ship today. Corrected there too -- claiming more than the code does is the one thing this audience does not forgive. Explainer archetype amended: lead with whatever answers "what shape is this" fastest. Usually a diagram; on a permissions page an at-a-glance table beats one, because the shape is counts and categories. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The two pages a design partner hits within minutes of a first scan, and nothing described either of them. Written in that order deliberately: resolution is meaningless to someone who cannot yet interpret severity and evidence. The lifecycle table is the part worth getting right, and it is taken from FindingsEngine rather than from the feature spec. What TOPS actually does: a passing rule auto-resolves with reason "fixed"; a finding someone marked resolved that is still failing gets reopened with the reason cleared; an ignored finding that is still failing stays ignored. That asymmetry is the whole design of D-11 -- resolved is a claim about the world and evidence can contradict it, ignored is a standing judgement about the rule and evidence cannot. The pages say so in those terms. The row that earns its place is the last one: a scan that did not examine a service leaves those findings untouched. Silence is not treated as good news, and a reader who assumes otherwise would draw exactly the wrong conclusion from an empty list. resource_gone is deliberately not documented. It is a defined resolution reason but is deferred behind PERF-2, so only "fixed" and "manual" can occur today and only those two appear. Every number asserted was checked against the rulesets rather than carried over from the roadmap: 74 rules, 4 critical / 24 high / 32 medium / 14 low, 11 services, all 74 carrying remediation text. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
docs/quick-start.md described a Nuxt 3 + Serverless + Prisma + PrimeVue monorepo and ended with "Ready to proceed? I'll start initializing the project structure". None of that stack is the product: TOPS is Laravel and Inertia on Docker Compose. It was linked from docs/README.md, from docs/architecture.md as "setup instructions", and from app/DOCS.md as "Essential Setup", so anyone following the documented path was being sent 253 lines in the wrong direction. Deleted rather than ported. Per D-10 the README is canonical for install, so all four inbound links now point there instead. Incidental, found by the same link check: every relative link in docs/features/features-spec.md was written as ../docs/X from inside docs/features/, which resolves to docs/docs/X -- thirteen dead links in one file. Fixed, along with a reference to a practices/frontend.md that has never existed; that content is in practices/design.md. docs/, app/DOCS.md and README.md now have no dead relative links at all. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What and why
D-10 chose
user-docs/, plain Markdown, and a renderer decided later. This starts the directory and tests that choice against the hardest page in the plan rather than the easiest — an explainer with three complex SVG diagrams, written for security reviewers evaluating TOPS for their AWS organisation.The choice holds. CommonMark plus tables carried the whole page. The full requirement list turns out to be: Markdown with tables, static assets served alongside, and a theme whose image CSS is one rule away from correct. Every MkDocs- or Docsify-class renderer meets that. Nothing found here argues for a framework, so the deferral stands.
User story
Not a feature. Documentation plus design, against the roadmap's User documentation site workstream and D-10.
What is in here
Four pages written, the priority-1 set from the content map:
start-here/how-tops-connects-to-aws.mdaws-accounts/what-the-iam-role-can-do.mdusing-tops/reading-a-finding.mdusing-tops/resolving-a-finding.mdPlus
SECURITY.mduser-docs/assets/diagrams/*.svguser-docs/README.mddesign/docs-site/information-architecture.mddesign/docs-site/archetypes/*.mddesign/docs-site/wireframes.htmldesign/architecture/docs/quick-start.mdFindings worth reading before writing the next page
Two bugs that only exist once a diagram is standalone. Both fail as a broken image, which reads as a missing file rather than a syntax error:
.svgis parsed as XML, so—makes the file fail to render entirely. All numeric references now.The diagrams were re-authored at a 900px viewBox. Carried over at 1160px from the full-bleed HTML page, they scaled to 7.5px body text in a docs column — unreadable. At 900px with larger type and zones stacked vertically, they hold above 10px down to an 820px viewport:
This withdraws a recommendation the design itself first made. An earlier draft proposed a wide-layout variant for explainer pages; it was compensating for over-wide diagrams. With them sized correctly the standard layout is enough and the site keeps one layout instead of two.
Theme requirement, in full:
main p:has(> img) { max-width: none }(Markdown wraps images in a<p>, so the prose measure silently caps every diagram at 686px), plus the usual responsive breakpoints. That is all.How it was tested
No application code changed, so no test suite ran. The page and diagrams were verified by measurement, not by eye:
xml.etree.ElementTree) — this is what caught both entity bugs.getBBox()against its containing rectangle: found a 4px card overlap and a text run escaping its card, both invisible in review, both fixed. Final state is clean — no overflow, no collisions, nothing outside the viewBox.Quality gate
docs/practices/— no page written for a feature that does not exist, verified againstPROGRESS.mdPractices check
Multi-tenancy, Database and Scan definitions are untouched.
Out of scope
docs.teemops.comdoes not resolve yet.README.md's setup section to link intouser-docs/. Worth doing once there is an install page to link to; doing it now would point at nothing.teemops.commarketing site — different worktree, per the brief.Two decisions for the reviewer
user-docs/to start from "you're logged in", withREADME.mdcanonical for install. That holds for operators but not for reviewers, who read before anything is installed and will not open a GitHub README to do it. The proposal:user-docs/owns evaluate and use;README.mdstays canonical for the commands and the site links out. Not recorded in the log yet — that is your call.Findings from writing the pages
Both came from reading the code rather than restating the specs, and both changed what the docs say.
The child IAM role's write permissions are not used by anything. TOPS instantiates only STS, SNS and SQS clients — there is no SecurityHub, GuardDuty, Macie, Inspector, Config or CloudTrail code in the repository, and all 36 operations declared across
rules/tasks/*/tasks.jsonarelist,getordescribe. So the role asks customers for write access across eight services on behalf of features that do not exist. Both pages say so, and show how to strip them. Worth its own issue: trim the template to what is used.Also:
s3:ListAllMyBucketsinTopsS3Bucketcan never authorise — it does not support resource-level permissions and the statement scopes it toarn:aws:s3:::tops-config-*. Inert, but a reviewer would find it.Two gaps closed.
SECURITY.mdnow exists, and the deaddocs/quick-start.mdis deleted with its four inbound links repointed at the README.Two blockers on SECURITY.md
The policy names two channels and neither answers yet:
security@teemops.comdoes not exist and needs routing.🤖 Generated with Claude Code