StrictDoc

repository·main·Indexed 43 days ago

https://github.com/strictdoc-project/strictdoc

Open-source software for technical documentation and requirements management. It allows users to write requirements in a structured format using .sdoc files and export them to static HTML or preview them via a local web server. The tool includes features for ASD-STE100 simplified technical English rewrites to ensure high-reliability text for AI agents and non-native readers.

Tokens
48.9K
Snippets
103
Records
223
Agent score
52%

What's inside StrictDoc

  1. Use the ASD-STE100 skill for controlled-language rewrites

    main

    The asd-ste100 skill is used to rewrite English text into Simplified Technical English (ASD-STE100). This is specifically designed for text that will be parsed by an AI agent or a downstream system (e.g., tool descriptions, error messages, system prompts, or inter-agent instructions) where ambiguity carries a high cost.

    When to use:

    • When text is dense, jargon-heavy, or ambiguous.
    • When text is consumed by another agent, a translation pipeline, or a non-native reader.
    • When writing prompts or tool descriptions to ensure an LLM cannot misinterpret them.

    When NOT to use:

    • For creative or marketing copy. The output is deliberately flat, literal, and lacks nuance or persuasion.
  2. Understand the Inline Form Lifecycle

    main

    Every editable field follows a standard request/response lifecycle using Turbo Streams:

    1. GET (Fetch Form): Clicking a display triggers a GET request to the URL in the field's data-url (e.g., get_node_contenteditable_inline, get_node_autocomplete_inline, etc.). The request must include Accept: text/vnd.turbo-stream.html (TURBO_ACCEPT).
    2. Turbo Stream (Swap): The server returns a Turbo Stream that swaps the field's display content for an editable form, scoped to the target ID (e.g., <div id="cell-{mid}-{FIELD}"> or <div id="doc-field-{mid}-{FIELD}">).
    3. POST (Save): On blur, outside click, or Ctrl/Cmd+Enter, the JS serializes and POSTs the form to the matching update endpoint (e.g., update_node_field, update_node_comments, update_document_custom_meta).
    4. Turbo Stream (Result):
      • Success: A Turbo Stream re-renders the field's display.
      • Validation Error: A Turbo Stream re-renders the active field along with sdoc-form-error markers.
  3. Use Bottom Line Up Front (BLUF)

    main

    Use a deductive writing style by employing BLUF (bottom line up front). State the conclusion, key point, decision, or request at the very beginning, before providing supporting details, reasoning, or background.

    Goal: Allow readers to understand the main point immediately without having to read the entire message, reducing cognitive effort.

  4. How content viewport stability works in StrictDoc

    main

    StrictDoc uses a stateful viewport controller (content_viewport_restoration.js) to prevent visual jumps (layout shifts) when the document geometry changes due to lazy loading, content replacement, or resizing.

    Instead of tracking raw pixel offsets, the controller uses semantic viewport snapshots. A snapshot identifies a witness (a meaningful document element, preferably a visible sdoc-node) and its position. When the DOM changes, the controller finds the same witness in the new DOM and adjusts .main.scrollTop to compensate for the movement.

    The Restoration Sequence:

    1. Record: Before DOM changes, capture a semantic viewport snapshot (the witness and its position relative to .main).
    2. Mutate: Allow the DOM mutation (e.g., Turbo rendering a chunk) to occur.
    3. Locate: Find the same semantic element in the updated DOM.
    4. Measure: Calculate how far the element moved relative to .main.
    5. Compensate: Adjust .main.scrollTop by the exact difference.
    6. Protect: Continue protecting this position through subsequent asynchronous changes (like placeholder height removals) using a generation system to ignore obsolete updates.
  5. Handle near-simultaneous loading of multiple chunks

    main

    StrictDoc is designed to handle multiple chunks loading at nearly the same time without geometry errors.

    When multiple chunks are switched to loading="eager" in a single JavaScript task, the system must:

    1. Allow responses and frame mutations to complete independently.
    2. Ensure that the cumulative geometry delta is applied correctly.
    3. Prevent 'double-counting' geometry: A common regression involves one lock compensating for both chunks but only updating its own baseline, causing the second lock to apply the same delta again. StrictDoc solves this by synchronizing all current passive baselines after each correction.
  6. Identify Scenarios Requiring Viewport Stability Management

    main

    The controller must manage viewport stability during the following events:

    • Lazy Loading: When a lazy placeholder is replaced with rendered nodes, or when an estimated height for a placeholder is removed.
    • Document Replacement: When the complete frame_document_content DOM is replaced following a server operation, or when the replacement introduces new lazy placeholders.
    • Content Mutation: When content that has already been inserted changes height, or when a user creates, deletes, moves, or edits document content.
    • Non-chunked Operations: When the same server operations are performed on a document that is not chunked.

    Note on User Intent: The controller must respect newer user intent. If a user scrolls or navigates after a position was recorded, the controller must not allow an older asynchronous callback to return the viewport to the previously recorded position.

  7. How StrictDoc favicon variants are resolved

    main

    StrictDoc uses a single Jinja template (strictdoc/export/html/templates/_shared/favicon.svg.jinja) to render different favicon variants based on the execution environment. This allows the favicon to adapt to development, testing, or production/export modes, as well as the user's light/dark color scheme.

    Environment Mapping

    The variant is determined by the following logic:

    • test: Set when STRICTDOC_ENV=test is present (used by SDocTestServer).
    • dev: Set when the --development CLI flag is used (e.g., via invoke server).
    • export: Set when running a static strictdoc export or HTML2PDF export.
    • default: The fallback for a standard, live, non-dev, non-test server.

    Technical Details

    • Color Adaptation: Each variant defines its own light_color and dark_color pairs used via @media (prefers-color-scheme: light/dark).
    • Rendering Lifecycle: The favicon is rendered once per process by HTMLGenerator.export_assets() and written to _static/favicon.svg, overwriting any existing static file. It is served as a plain file from disk.
    • Testing: The root <svg> includes data-testid="{{ variant }}-favicon" to allow unit tests to verify the rendered variant without relying on color values.
  8. How Markdown grammar validation works

    main

    StrictDoc uses a permissive reading model for Markdown but a strict validation model for document integrity.

    1. Reading: The MarkdownReader is permissive and does not assume the document is constrained only to default elements (like REQUIREMENT, SECTION, or TEXT). It allows arbitrary elements as defined by your custom grammar.
    2. Validation: Document integrity is enforced by the TraceabilityIndexBuilder via the SDocValidator.validate_document(document) method. This ensures that even though the reader is permissive, the actual content adheres to the schema defined in your .gra.md grammar file.
  9. Behavior of Relation cells in TABLE VIEW

    main

    In StrictDoc's TABLE VIEW, the editability of a Relation cell is determined by the node type's grammar.

    • Editable Cells: A Relation cell is only editable if the grammar of the specific node type declares at least one relation type.
    • Inactive Cells: If a node type does not declare any relations in its grammar, the Relation cell is rendered as a dimmed, inactive cell, consistent with other unavailable grammar fields for that node.
  10. Detection guidance: Signs of human writing to preserve

    main

    When the following patterns are present, lean toward leaving the prose alone to preserve its human quality:

    • Specific, unusual detail: Real addresses, weird quotes, or highly specific anecdotes (e.g., "the lawyer who used to work upstairs from my dentist").
    • Mixed feelings/unresolved tension: Prose that expresses nuance or inability to reach a clean conclusion.
    • Era-bound references: Slang, memes, or in-jokes tied to a specific year or subculture.
    • Sentence variety: Alternating between short and long sentences (AI tends toward a mid-length cadence).
    • Genuine asides/self-corrections: Parentheticals where the writer interrupts themselves (e.g., "(I keep wanting to say 'almost' here, but it really was certain.)").
    • Pre-2022 content: Any text edited before November 30, 2022, is highly unlikely to be AI-written.
  11. How Tree Map data is generated and rendered

    main

    The Tree Map uses a split architecture between Python and the Browser to handle complex project data.

    Data Generation (Python)

    Python is responsible for preparing the hierarchy and the StrictDoc-specific data. This design allows users to define custom logic for what a tree map displays by adding user-defined functions in Python without needing to modify the browser-side renderer.

    Rendering (Browser)

    The browser receives the hierarchy as a JSON object. The renderer is responsible for:

    • Calculating the layout (using weight-based sizing).
    • Managing visual constraints (minimum node dimensions, visibility thresholds).
    • Handling synthetic groups (grouping nodes when there are too many direct children to preserve usability).
    • Managing the DOM (limiting visible depth and node count for performance).

    JSON Contract

    The JSON data follows a specific contract:

    • Labels and Counts: These are kept as separate values. The renderer exposes the count via the data-count attribute on the label element.
    • Identifiers: Each serialized node must have a stable identifier.
  12. Understand Content Viewport Stability and the Witness Concept

    main

    In StrictDoc, the DOCUMENT screen must maintain visual stability for content currently in view when asynchronous rendering changes the document's geometry.

    Visual stability is achieved by selecting a witness: a meaningful visible element that the controller tracks. Instead of relying on the scrollbar's numeric position (scrollTop), the controller records the witness's position relative to the .main viewport and ensures it remains at that same coordinate after geometry changes.

    The Stability Requirement: witness_top_after == witness_top_before

    This mechanism is necessary because:

    • Lazy placeholders being replaced by real DOM nodes can have different heights than their estimates.
    • Full frame_document_content DOM replacements (e.g., after server operations) invalidate previous scroll positions.
    • User edits, deletions, or moves change the document structure.
    • Native browser scroll anchoring is insufficient because it cannot track elements across DOM replacements or handle specific application-level logic like deletion boundaries.
    witness_top_after == witness_top_before