Fire up the Observer
USER GOAL:
Finish introducing the "Issue Resolution" collection to the observer system by implementing a watcher.
Working Directory
content/lost-in-public/issue-resolution
STEPS:
Step 1: Audit the Metadata
- Read the rest of this file for the context window.
- Systematically audit the metadata of each file within the
content/lost-in-public/issue-resolution
directory. For each file: a. Parse its frontmatter. b. Compare its structure against the expected pattern for 'Issue Resolution' items (refer to thetidyverse/observers/templates/issue-resolution.ts
template for the expected structure and the "Ideal Data Example for Issue Resolution" section below). c. Log any identified inconsistencies, errors, or missing mandatory fields. Proceed through all files without requiring intermediate confirmation for each.
Step 2: Understand the Patterns and Architecture of the Observer and Watcher System
- Read the other watcher files in
tidyverse/observers/watchers
to understand the pattern, including the imported handlers, utils and services. - Read the master orchestration in
tidyverse/observers/index.ts
,tidyverse/observers/userOptionsConfig.ts
, andtidyverse/observers/fileSystemObserver.ts
to understand the pattern, including separation of concerns, DRY principles, and the use of the propertyCollector. - Read the starter files previously created in
tidyverse/observers/templates/issue-resolution.ts
- Visualize the Flow: The following diagram illustrates how the new
issueResolutionWatcher.ts
will integrate into the existing observer system:graph TD subgraph IssueResolutionWatcher Integration A[File Event in 'content/lost-in-public/issue-resolution'] --> B(FileSystemObserver); B --> C{PropertyCollector Check}; C --> D[issueResolutionWatcher.ts]; D --> E[Read 'issue-resolution.ts' Template]; D --> F[Process Frontmatter (yamlFrontmatter.ts)]; F --> G[Apply Handlers (e.g., addSiteUUID.ts)]; G --> H[Write Updated File]; end - Understand the Target Data Structure (Ideal Data Example for Issue Resolution): The goal of the watcher is to ensure that frontmatter for 'Issue Resolution' items is consistent and complete. Here's an example of an ideal, fully processed frontmatter for an item in the
content/lost-in-public/issue-resolution
directory:yaml--- title: 'Specific Issue Title' lede: 'Short description of the issue and its resolution.' status: 'Resolved' # Expected values: 'Reported', 'Investigating', 'Pending-Fix', 'Resolved', 'Wont-Fix' date_reported: YYYY-MM-DD date_resolved: YYYY-MM-DD # (nullable if not resolved) affected_systems: ['System A', 'Module B'] # (array of strings, optional) severity: 'Medium' # Expected values: 'Low', 'Medium', 'High', 'Critical' (optional) resolution_summary: 'Key steps taken to resolve the issue, or current status.' tags: ['bug-fix', 'database', 'specific-module'] # (standard tags) site_uuid: 'auto-generated-uuid-12345' # (auto-generated by addSiteUUID.ts handler) # Add any other fields defined in tidyverse/observers/templates/issue-resolution.ts ---
Refer totidyverse/observers/templates/issue-resolution.ts
for the canonical template definition. - Suggest the best way to implement a watcher for the issue resolution collection.
Step 3: Implement the Plan
- Define Key Characteristics for
issueResolutionWatcher.ts
: Before coding, clarify the following for the new watcher:- Input:
filePath
: string (absolute path to the changed file)fileContent
: string (content of the file)frontmatter
: object (parsed frontmatter from the file)dirConfig
: object (the specific configuration for the 'issue-resolution' directory fromuserOptionsConfig.ts
)
- Primary Logic:
- Validate and conform
frontmatter
againsttidyverse/observers/templates/issue-resolution.ts
. - Apply relevant handlers (e.g.,
addSiteUUID.ts
, and potentially others specific to issue resolution if needed).
- Output:
- Object containing the
updatedFrontmatter
(object) andupdatedFileContent
(string) if changes were made. - Return
null
or an equivalent indicator if no changes are necessary.
- Side Effects:
- Logs its processing activity clearly.
- Interacts with the
propertyCollector
to register expected changes and prevent loops.
- Implement the plan.
- Test the implementation focused on the "issue resolution" collection subsystem on the
content/lost-in-public/issue-resolution
directory. - Run all the subsystems at once to see if they work together.
The Observer System
This document provides instructions for augmenting, improving, or running the filesystem observer to process new files within specified directories that contain a unique content collection for rendering on the website.
Previous Mistakes:
- Infinite Loops: The observer was triggering itself, leading to an infinite loop. This was resolved by adding a universal "propertyCollector" in the main observer, which then delegates all tasks to the appropriate watchers, handlers, services, and utils. The propertyCollector immediately receives an "expectation" object, which is a list of properties that will be created or modified by the watchers, handlers, services, and utils. The propertyCollector also includes a cooldown period and an in-memory log of files that have been processed.
- Random Frontmatter Corruption: When introducing new functionality to the observer system, functionality that had already been honed and was error free would be duplicated for convenience of Code Generation and reasoning within one file. But, the use of regular expressions and text manipulation to extract, evaluate, generate and update frontmatter created inconsistencies, and sometimes glaring errors that corrupted entire directories of content, which then needed to be fixed. We have MAINLY solved for this by using DRY principles and keeping extraction, evaluation, and update logic in a single-source-of-truth that is used by all watchers, handlers, services, and utils. IT IS CRITICAL TO FOLLOW THIS PRINCIPLE AND NOT UNNECESSARILY DUPLICATE FRONTMATTER TRANSFORMATION LOGIC ACROSS FILES.
Integrated Observer System
Independent Watchers for Collections
tidyverse/observers/watchers
We decided to avoid repeating a monolithic FileSystemObserver that handles all collections. There were several key moments where one collection was being corrupted by the monolithic observer, and it was not possible to isolate the issue. We would then need to move the fileSystemObserver
file to the archive, and start from scratch.So, instead, we will have independent watchers for each collection. This involves repeating a number of functions across separate watcher files, but it is a necessary evil to ensure that each collection is processed correctly. And if there is a glitch for one collection, the remaining watchers can stay active in the observer.
List of Watchers
tidyverse/observers/watchers/conceptsWatcher.ts
tidyverse/observers/watchers/vocabularyWatcher.ts
tidyverse/observers/watchers/essaysWatcher.ts
tidyverse/observers/watchers/remindersWatcher.ts
tidyverse/observers/watchers/promptsWatcher.ts
tidyverse/observers/watchers/toolkitWatcher.ts
List of Templates
tidyverse/observers/templates/concepts.ts
tidyverse/observers/templates/vocabulary.ts
tidyverse/observers/templates/essays.ts
tidyverse/observers/templates/reminders.ts
tidyverse/observers/templates/prompts.ts
tidyverse/observers/templates/specifications.ts
tidyverse/observers/templates/issue-resolution.ts
tidyverse/observers/templates/tooling.ts
List of Handlers
tidyverse/observers/handlers/addSiteUUID.ts
tidyverse/observers/handlers/processOpenGraphMetadata.ts
tidyverse/observers/handlers/processScreenshotMetadata.ts
List of Services
tidyverse/observers/services/openGraphService.ts
tidyverse/observers/services/screenshotService.ts
List of Utils
tidyverse/observers/utils/extractStringValueForFrontmatter.ts
tidyverse/observers/utils/yamlFrontmatter.ts
List of User Options
tidyverse/observers/userOptionsConfig.ts
Unique Collections or Observers
Tooling and Toolkit
While other collections are rendered as articles in content layouts, the "toolCollection" or "toolingCollection" is rendered as a Card Crid, with visually rich cards displaying the tools and their metadata. Therefore, we use third party APIs to generate screenshots and OpenGraph images for the tools, which are accessed through our services and handlers.
Found in:
content/tooling
Citation Processing
We have done one isolated run of a Citation Processor, and it works but the resulting format may not be optimal. We need to evaluate the output and make product decisions before we can integrate it into the core FileSystemObserver.
Running the Observer
To run the observer and process both citations and frontmatter:
bash
cd /Users/mpstaton/code/lossless-monorepo/tidyverse
pnpm start
This will run the
start
script defined in package.json, which executes ts-node observers/index.ts
.You can also specify a custom content root directory as an argument:
bash
pnpm start -- ../../content
This will:
- Start the FileSystemObserver
- Watch for file changes in configured directories
- Process citations in markdown files (convert numeric to hex)
- Validate and update frontmatter
- Generate reports periodically
How Watchers Work:
The observer system relies on a set of independent "watchers" to monitor specific content collections for new files or modifications. This modular approach ensures that each collection is processed according to its unique requirements and prevents issues in one collection from affecting others. Here's a breakdown of their operation:
- Configuration and Initialization:
- Watcher configurations are primarily managed in
tidyverse/observers/userOptionsConfig.ts
. This file defines which directories (collections) are actively monitored by the system. - The master orchestration script,
tidyverse/observers/index.ts
, initiates theFileSystemObserver
(detailed intidyverse/observers/fileSystemObserver.ts
). - The
FileSystemObserver
iterates through thedirectoryConfigs
fromuserOptionsConfig.ts
. For each configured directory, it sets up a dedicated file system watcher instance (typically using a library likechokidar
). - Each watcher is responsible for a specific content collection path (e.g.,
content/lost-in-public/prompts
,content/tooling
).
- Event Detection:
- Watchers are set to listen for file system events, primarily:
add
: When a new file is created in a watched directory.change
: When an existing file is modified in a watched directory.
- The
FileSystemObserver
includes a "propertyCollector" mechanism. This component is crucial for:- Receiving an "expectation" object, which lists properties that will be created or modified by downstream processes (handlers, services).
- Managing a cooldown period.
- Maintaining an in-memory log of processed files to prevent infinite loops and redundant operations.
- Processing Workflow (per file event):
- When a file event (add/change) occurs, the
FileSystemObserver
'sonChange
(or similar) method is triggered, receiving thedirConfig
for the specific file. - The system first consults the propertyCollector to ensure the file is eligible for processing.
- The task is then delegated to the appropriate processing pipeline, which involves a series of steps tailored to the collection:
a. Citation Processing (Conditional): * If applicable to the collection and enabled, citations within the markdown file are processed (e.g., converting numeric citations to hex format) using methods likeprocessCitationsInFile
.b. Frontmatter Processing: This is a core function involving multiple sub-steps: * Extraction: The existing YAML frontmatter is read from the file using utilities liketidyverse/observers/utils/yamlFrontmatter.ts
. * Validation & Templating: The extracted frontmatter is validated against a predefined template specific to the collection (e.g.,tidyverse/observers/templates/issue-resolution.ts
for the issue resolution collection). This step ensures consistency and completeness. * Applying Handlers: A set of handlers fromtidyverse/observers/handlers/
are invoked to modify or add frontmatter properties. Common handlers include: *addSiteUUID.ts
: Ensures every content piece has a uniquesite_uuid
. * Specialized handlers likeprocessOpenGraphMetadata.ts
orprocessScreenshotMetadata.ts
may be used for specific collections (like 'tooling') that require integration with services (tidyverse/observers/services/
). * Normalization & Enrichment: Property names are normalized, and missing required fields (as defined by the template) are added. * Updating: The modified frontmatter is written back to the file usingtidyverse/observers/utils/yamlFrontmatter.ts
. - Logging and Reporting:
- Throughout the process, detailed logs are output to the console, indicating files being processed, specific actions taken (e.g., citations converted, frontmatter updated), and any errors or warnings encountered.
- The system may also generate periodic reports summarizing its activity.
How Citation Processing Works
As detailed in the "Processing Workflow" of the "How Watchers Work" section, citation processing is a conditional step triggered by a watcher when a new or modified markdown file is detected in a relevant collection.
If enabled for the collection, the
processCitationsInFile
method (or a similar utility) is invoked. This method typically performs the following actions:- Converts Numeric Citations: Identifies numeric citations within the content and converts them to a standardized format (e.g., hexadecimal).
- Updates Citation Registry: Maintains a registry or database of all citations encountered, ensuring consistency and enabling features like a master bibliography.
- Generates Footnotes: If the citation style requires it, this step automatically creates or updates a footnotes section at the end of the document.
It's important to note, as mentioned earlier, that while an isolated citation processor has been tested, its output format is pending further evaluation to ensure it meets product standards before wider integration into all relevant observer workflows.
Monitoring Results
The observer will output logs to the console showing:
- Files being processed
- Citations being converted
- Frontmatter being updated
- Any errors or warnings
Reports are generated in the
content/reports
directory every 5 minutes and when the observer is shut down.