npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@signatu/policyengine

v0.213.0

Published

signatu policy engine

Downloads

24

Readme

Policy Engine

The goal of the new engine is to build a robust, safe, extensible and maintainable Policy engine that can support multiple languages and output formats.

The new engine will be built using TypeScript to leverage compile-time type safety. The engine will be built to be run either on the server under node.js, or in the browser.

Design

A diagram is maintained at Draw.io

Design

Concepts

A Policy is a representation of the Privacy Policy the user has created by answering Questions. The answers will result in one or more PolicyClause, of the following type:

  • Pre-defined static clauses
  • Pre-defined clauses from a mutually exclusive list, including possible "specify..." input.
  • Pre-defined clauses from multiple selections from a list, including possible "specify..." input.
  • Free-text input

A PolicySection represents a section that considers a certain topic, e.g., "Transfer of Data". Both PolicySection and PolicyClause implements the PolicyElement interface. A Policy is hence an ordered list of objects that implement PolicyElement.

A PolicyGenerator will generate a PolicyDocument from a given Policy. Typically there will be different PolicyGenerator implementations for the different output formats, and possibly languages.

Multiple languages and outputs

All the predefined clauses has a text in controlled English language that serves as the "master" text. All other representations (e.g., plain language German, legal language French) are considered derivatives of this controlled text, and should mirror its meaning as closely as possible.

The user-specified input will as a rule not be provided in a controlled English, hence it may require translation to allow for output in other formats.

Design

Here we'll write up the general flow of alternative options. There are three complicating factors:

  1. Each question can result in different clauses depending on the option the user chooses
  2. Clauses can be output in different languages and formats (e.g., pictures)
  3. Clauses can include user-specified input texts, written in a non-controlled, natural language (e.g., German).

Basics

The PolicyElement corresponds to a specific option for a Question, referencing user-specified input through a UserInput object. A PolicyElement will have a set of PolicyContent objects associated with each option, one for each language and potentially other types as well (e.g., pictures).

Scenarios

Create the questionnaire

The Questionnaire is structured as an ordered list of Sections, who all have an ordered list of Questions. Each Question option has a single PolicyElement associated with it, specifically a PolicyClause. The masterText is the controlled English for the clause.

To add actual content to the PolicyElement, one or more PolicyContent is added to the PolicyElement. For example, a TextContent object having language: en can be added to make an English plaintext version of the clause.

Answer a questionnaire”

Each Question is presented to the user. When a particular option is chosen, it is connected to a particular PolicyElement, and the PolicyElement is added to the Policy. If the PolicyElement requiresInput, then collect input from the user, and add that to the Policy as well. The UserInput will reference the PolicyElement it contains input for. This will be used by the PolicyGenerator.

Generate a policy

A PolicyGenerator will create output based on a Policy and some parameters, such as the language, type of output (text, pictures, etc) and so on.

The generation is pretty straightforward:

  1. For each PolicyElement:
  • Get the correct associated PolicyContent object. When generating a text-based policy in English, for example, the right object would be a TextContent having language: en.
  • If the PolicyContent requires/has input, get the associated UserInput object and provide the generate() method.
  1. Combine the output of each PolicyElement in sequence into the final PolicyDocument.
  2. Repeat for different parameters (e.g., language).

User input

Some questions require the user to "specify" further - e.g., the type of processing, the retainment time for data, and so on. This input is merged into the PolicyContent from PolicyElement. Note that a PolicyElement can have multiple PolicyContent - different languages, different formats (icon, speech, video), so we need to be able to track multiple UserInput for each PolicyElement.

We want the PolicyElement and PolicyContent objects to be the same across different Policies, so the current thinking is to provide UserInput[] to a PolicyContent.generate() function.

We'll use Mustache to render user input. All UserInput objects have a given name, and that name is substituted for {{name}} in the PolicyContent text.

Metadata

Some of the PolicyContent are template strings - e.g., "{{controller.name}} processes data in the US". The meta data may be in different languages and formats, too. Meta-data is also handled with Mustache, where the Policy metaData is passed. If the text contains e.g., {{controller.name}}, then we expect meta data to have an object controller with a property name.

Generate a clause for an external service

E.g., Google Analytics. This is equivalent to the others - an ExternalService object (which implements PolicyElement) is added to the Policy. The appropriate PolicyContent objects are added to the ExternalService - e.g., IconContent .

Discussion

It would be beneficial of two PolicyDocuments containing the same PolicyElement can be said to be legally equivalent for that particular area, and that the legal consequences are similar. This may be difficult in practice, but if possible, it would ease reasoning over policies, finding similar policies and so on.

Open Questions

  • Should UserInput just be a class implementing PolicyContent?
  • Should the generate() method be moved out of the PolicyContent interface? How do we control generation to different formats - e.g., plain text, HTML, JSON, XML, PNG, etc?
  • Do we need to separate PolicySection and PolicyClause? Can't both of them just be a PolicyElement?

Answered Questions

  • How to associate the UserInput without creating a new PolicyElement for each Policy? => associate it with both the Policy and the PolicyElement (one way only). Hence when generating a policy, we keep track of the input for all the PolicyElements.