Overview
People Work exists to help managers and their engineering teams better manage the people side of their jobs. In short it helps a manager become a better manager and an employee better engage the performance management process.
Motivation
As a technical manager, you started your career in a technical capacity with lots of tools at your disposal, the loveliest and most used of which was your IDE of choice. I’m sure you can think of 3 or 4 tools off the top of your head that you used daily. Can you imagine having done your engineering job without them?
Then you became a manager, and suddenly the landscape of tooling was abysmal. You have the HR-approved tooling that you mostly just use to approve time off and submit performance reviews with. Beyond that, you probably just use Word or Google Docs to keep track of 1:1 notes for each of your direct reports. They’re such big files that you rarely go back and read anything because it’s really hard to find. Then when review time rolls around, you fall prey to the bias of the present. You talk about their last couple of projects and can’t remember anything that happened more than 6 weeks ago.
What if you had an IDE for managing your team? Just like during your technical days, you had an IDE to help you with best practices, like unit testing, builds, compiling, etc. What if you had an IDE to help you with 1:1s, reviews, feedback, and other performance related things? Think of how much more successful of a manager you would be for your team if you had a world-class tool helping you rather than a tool for someone else that makes you feel like you’re just checking off a box.
And what if this tool was so good that your technical team actually used it to engage in their own career growth, resulting in them being more engaged and more productive team members? Those types of teams and leaders are rare. We build the tooling to create those outcomes and make your journey as manager as short and upwardly mobile as possible.
You may think of this as a typically HR tool, and you're right - it is! But we are here to partner with HR in order to enable managers and employees to do better at managing relationships in order for HR to manage more strategic outcomes.
Installation
To run the application, pull the code, run just cs
, and run the code in XCode.
macOS Configuration
If you want to navigate our forms via the keyboard through tabbing, you should configure your System Settings:
- Open up System Settings on your Mac
- Search for "Mission Control" and click on "Keyboard and Mouse Shortcuts" on the left
- In the "Keyboard Navigation" section on the right, click on "Keyboard Shortcuts"
- Ensure the "Keyboard Navigation" tab is on
Overview
This app creates an operating system for working with others. Just as in a computer's operating system you have processes for things like managing files and applications, in this operating system we provide an opinionated framework of processes to navigate complex human people systems.
These processes are divided into three sections:
- Get Control Of Your Time - Segment, Plan, Track
- Manage Performance - Assess, Align, Track
- Onboard Your Team
Get Control Of Your Time
flowchart LR
A[Segment]:::teal --> B[Plan]:::teal
B[Plan] --> C[Track]:::teal
classDef teal fill:#000000,stroke:#66cccc,color:white
Getting control of your time is foundational in People Work. The exercise of segmenting, planning, and tracking the professional relationships that are most impactful to your career will allow you to maximize your effectiveness and really enjoy the connections along the way.
Below are some questions you'll need to be ready to answer while you onboard yourself to People Work.
Segment
Who are your people? This list should be purposeful and precise, not a catch-all. Make a list of all the people that fit into the following categories:
- Direct Reports - those that report to you or are looking to you for leadership
- First Team - those who report to your same boss or are peer to you and share your same objectives
- Stakeholders - those with a vested interest in your outcomes — mentors, leadership, project stakeholders
- Base - these connections are less frequent but still meaningful professional relationships who help you maintain broader influence beyond your immediate sphere
Plan
Think about your intentional support of and from each person. How often should you meet in order to achieve this mutual support?
Track
Each relationship requires us to remember so much! What are the needs of each relationship that you will use People Work to help you keep track of? How is the health of each of these connections currently?
Manage Performance
The term "manager" in this document is used generically to reference anyone managing performance, whether that be of a direct report or your own.
Whether you're managing others or yourself, you can effectively manage performance within three phases:
Align
First, align on expectations. The employee is assigned a job in the system, and those jobs have expectations that fit within a Career Matrix.
These expectations for the employee's job help the manager get clear with the employee about what the employee is being measured on.
The manager also sets an expectation with the employee of their intention for how often to check in.
Track
The manager and employee then both track what happens and how it relates to their performance, via a journal of connections. This ultimately creates evidence for the next conversation.
Assess
Now that expectations are set via alignment and evidence is gathered for how the employee met those expectations, it's time to assess performance.
The manager is able to review the journal and come up with an assessment.
Onboard Your Team
Just in the same way that managers are able to use People Work to manage their teams, individual contributors can use People Work to track their own performance and goals.
With a system in place for relationships and performance, it’s now time to scale that to others; first with your team and then with your broader organization.
flowchart LR
A[Onboard]:::teal --> B[Share]:::teal
B[Share] --> C[Report]:::teal
classDef teal fill:#000000,stroke:#66cccc,color:white
Onboard
There are two ways you can invite someone to your workspace:
-
Share a workspace template with others who can quickly get started without having to enter in basic information for people, jobs, career matrices, or values, all while maintaining your privacy as well as theirs.
-
Automatically onboard to a shared service, which provides this information for you (coming soon).
Share
While privacy is a core value of People Work, there is some sharing that is necessary for growth and convenience. Those are noted here:
- You are encouraged to share your workspace data with others.
- You can share your workspace context, the files within your workspace directory, with AI in order to gain insights and see patterns.
Report
As more and more teams begin to use People Work and more senior leadership views the app, you can create spreadsheets from the data so that they can see things like:
- Aggregate and specific details of how managers rate their employees and where there is a delta
- Timeline of aggregated details over time, for example calibration, to see if managers are engaged
Workspaces
Workspaces are the fundamental grouping, or tenant, used in the app. A workspace is located within a folder that fits a very specific structure outlined in the dsl section below.
You can use a workspace in any way you like, but we recommend keeping it simple and doing one for work and perhaps one for your professional network outside of work.
When sharing a workspace, the following items are shared:
- Assets such as avatar images
- Members (but not the users' contacts)
- Career Matrices + Jobs
- Company Values (coming soon)
Onboarding
When you first open the People Work app, you will see a screen like this:
If you have a shared workspace from another member of your organization, then you will click "Open Existing Workspace..." and navigate to that workspace.
If you are creating a new workspace, then you will see a form to create a new workspace when you click on "Create New Workspace...". Here is an example of a filled out form:
Once you save, you will see an empty workspace with only your workspace in it.
Once you have added all of the contacts that wish to add (see Segment) via the UI or the contact
in the DSL, you will see all of your contacts in your workspace like so:
You're now ready to start using the app!
DSL Overview
This section outlines our custom domain specific language for the application.
Motivation
We started developing these features in a much more conventional way, as a web application connected to a SQL database. As we used the app, we felt something was missing:
- Ownership - For true growth to happen, we know that honesty and vulnerability are key, two things that we feel strongly about enabling in our app. We wanted our users to feel safe to share about their private goals and sensitive work relationships in our app, and in order to better facilitate that, we wanted to let our users own their own data, not for it to be in the cloud where someone else had control over it.
- Visibility - We wanted the user to know exactly what the app was storing, no hidden data that they couldn't control.
- Insights - We want AI to be able to easily read and comment on the data but in a way that the user can control.
This DSL is our answer to those problems. It enables a private, locally stored database that is human readable and, with a bit of training, human writable.
Once onboarded, a user can choose to only interact with their workspace through the desktop application, however, the DSL will remain at the core.
Workspaces
At the core of our DSL is a workspace, which is a logical group of people that the user can relate to. Most people will have a workspace for their place of employment. But other people may choose to track their professional relationships outside of work and in other areas as well.
Workspace Structure
Workspaces are structured by convention:
- ./core.ppl contains the
core
, shareable concepts that make up the workspace, like members, jobs, and matrices. This is meant to be shareable with others in that same organization, to help them get started faster. - ./people.ppl contains the user-specific connection to
the
core
. Here declares themselves as theuser
and determines who their contacts are.They also set anintention
for how to connect with each. - ./work this is where the user tracks their work for themselves and each of their contacts. This is in the form of journaling connections
- ./assets this is where files are stored that the workspace relates to.
Console App
We provide the people
command line application in order to help you work with a workspace
without having to open the full app. There are two commands to use:
people init
Will set up a new workspace.
people check
Will ensure that a workspace is valid.
This tool is self documenting so run:
people
To learn about all the options.
Visual Studio Code Extension
We also provide a Visual Studio Code Extension for this DSL, which provides syntax highlighting.
Core
The core
is stored in ./core.ppl
. It is the part of the workspace that could
easily be shared with other people in their organization, therefore it does not
contain any private or user-specific data in it. The core
consists of
members, jobs, and matrices.
Member
A member
is a part of the core
and stored in ./core.ppl
of
the workspace. It tracks the basic and widely available information for a person
or employee within an organization. A member
also has an avatar
which is stored by their id
.
Fields
first_name
- (Required) The first name of the person -String
last_name
- (Required) The last name of the person -String
job
- (Optional) The identifier of the job the person has, in order track their performance or as an optional reference. -Identifier
email
- (Optional) The person's email -String
Examples
Minimal
member alex_rivera {
first_name: "Alex"
last_name: "Rivera"
}
Full
// avatar stored at ./assets/avatars/tara_johnson.jpg
member tara_johnson {
first_name: "Tara"
last_name: "Johnson"
email: "tara@somecorp.com"
job: principal_software_engineer
}
Job
A job
is a part of the core
and stored in ./core.ppl
of
the workspace. It tracks the basic requirements for a position within an
organization, primarily for performance management purposes. It also
defines requirements within the career matrix.
Fields
The following arguments are supported:
name
- (Required) The human-readable name of the job -String
requirements
- (Optional) A map of requirements by category for this job. See the career matrix topic for a full description. This field's properties are dependent on what is defined there.
Examples
Minimal
// since there are no requirements, there should be no career matrix either.
job manager {
name: "Engineering Manager"
}
member alex_rivera {
first_name: "Alex"
last_name: "Rivera"
job: manager
}
Full
job software_engineer_1 {
name: "Software Engineer I"
requirements: {
technical: {
implementation: "Implements well-defined features with guidance"
code_quality: "Writes maintainable code following team standards"
code_review: "Participates in code reviews and bug fixes"
testing: "Learns testing best practices"
}
project_execution: {
delivery: "Delivers assigned tasks within expected timeframes"
clarity: "Seeks clarification when requirements are unclear"
updates: "Updates progress regularly"
process: "Follows established development processes"
}
problem_solving: {
debugging: "Debugs and resolves basic technical issues"
impact: "Understands how their code impacts immediate dependencies"
decomposition: "Learns to break down problems into manageable tasks"
}
collaboration: {
participation: "Actively participates in team meetings"
communication: "Communicates blockers and progress clearly"
feedback: "Receives and implements feedback effectively"
teamwork: "Works well with immediate team members"
}
growth: {
learning: "Demonstrates eagerness to learn new technologies"
initiative: "Takes initiative in skill development"
mentorship: "Seeks and accepts mentorship"
domain: "Builds understanding of product domain"
}
}
}
matrix software_engineering {
name: "Software Engineering"
categories: {
technical: {
name: "Technical"
description: "Core technical and architectural capabilities"
}
project_execution: {
name: "Project Execution"
description: "Delivery and implementation of technical work"
}
problem_solving: {
name: "Problem Solving"
description: "Technical problem solving and system thinking"
}
collaboration: {
name: "Collaboration"
description: "Working with others and leadership"
}
growth: {
name: "Growth and Learning"
description: "Personal and professional development"
}
}
jobs: [
software_engineer_1,
]
}
member kevin_osei {
first_name: "Kevin"
last_name: "Osei"
job: software_engineer_1
}
Matrix
A career matrix is a part of the core
and stored in ./core.ppl
of
the workspace. It tracks the structure of requirements for a family of
jobs in order to create clear career progression.
Fields
name
- (Required) - The human-readable name of the matrix -String
categories
- (Required) - A map of categories (detailed below) mapped by their category identifier, which is also used by the job requirments configurationjobs
- (Required) - A list of job identifiers that are a part of the career matrix. -[Identifier]
A category block is defined within the categories
block. It defines a single category of job requirements for each job in this matrix. It is identified by a unique identifier within the matrix that is used to define the job requirements. Each category has its own block.
name
- A human readable name of the category -String
description
- A human readable description of the types of requirements in this category -String
Categories and Job Requirements
Career matrices and jobs have a structural relationship with each other when defined together.
The matrix defines categories
, and the identifier of each category
(technical
in the minimal example below) is also defined as a requirement for
the job.
If this structure isn't exactly right, the workspace will fail to load, so someone configuring a matrix with jobs should make good use of the people app.
Examples
Minimal
matrix engineering {
name: "Software Engineering"
categories: {
technical: {
name: "Technical"
description: "Core technical and architectural capabilities"
}
}
jobs: [
software_engineer_1,
]
}
job software_engineer_1 {
name: "Software Engineer I"
requirements: {
technical: {
implementation: "Implements well-defined features with guidance"
}
}
}
member kevin_osei {
first_name: "Kevin"
last_name: "Osei"
job: software_engineer_1
}
Full
job software_engineer_1 {
name: "Software Engineer I"
requirements: {
technical: {
implementation: "Implements well-defined features with guidance"
code_quality: "Writes maintainable code following team standards"
code_review: "Participates in code reviews and bug fixes"
testing: "Learns testing best practices"
}
project_execution: {
delivery: "Delivers assigned tasks within expected timeframes"
clarity: "Seeks clarification when requirements are unclear"
updates: "Updates progress regularly"
process: "Follows established development processes"
}
problem_solving: {
debugging: "Debugs and resolves basic technical issues"
impact: "Understands how their code impacts immediate dependencies"
decomposition: "Learns to break down problems into manageable tasks"
}
collaboration: {
participation: "Actively participates in team meetings"
communication: "Communicates blockers and progress clearly"
feedback: "Receives and implements feedback effectively"
teamwork: "Works well with immediate team members"
}
growth: {
learning: "Demonstrates eagerness to learn new technologies"
initiative: "Takes initiative in skill development"
mentorship: "Seeks and accepts mentorship"
domain: "Builds understanding of product domain"
}
}
}
job software_engineer_2 {
name: "Software Engineer II"
requirements: {
technical: {
implementation: "Independently implements medium-sized features"
design: "Designs straightforward technical solutions"
code_review: "Provides thorough code reviews"
documentation: "Contributes to technical documentation"
}
project_execution: {
delivery: "Manages own deliverables reliably"
decision_making: "Makes informed technical decisions"
estimation: "Estimates work effort accurately"
risk_management: "Identifies potential risks early"
}
problem_solving: {
resolution: "Resolves complex issues independently"
system_thinking: "Considers broader system impact"
improvement: "Suggests process improvements"
optimization: "Identifies optimization opportunities"
}
collaboration: {
mentoring: "Mentors junior engineers informally"
cross_team: "Communicates effectively across teams"
technical_discussion: "Contributes constructively to technical discussions"
status: "Provides clear status updates"
}
growth: {
technical_growth: "Expands technical breadth"
domain_expertise: "Develops domain expertise"
feedback: "Proactively seeks feedback"
strategy: "Understands product strategy"
}
}
}
job senior_engineer {
name: "Senior Software Engineer"
requirements: {
technical: {
implementation: "Designs and implements complex features"
architecture: "Architects scalable solutions"
leadership: "Provides technical leadership"
best_practices: "Drives best practices adoption"
}
project_execution: {
initiative: "Leads significant technical initiatives"
technical_debt: "Balances technical debt with delivery"
architecture: "Makes sound architectural decisions"
quality: "Ensures quality of deliverables"
}
problem_solving: {
challenges: "Solves ambiguous technical challenges"
scaling: "Anticipates scaling problems"
solutions: "Creates systemic solutions"
processes: "Improves development processes"
}
collaboration: {
mentoring: "Mentors other engineers actively"
influence: "Influences technical decisions"
leadership: "Drives technical discussions"
cross_org: "Works effectively across organization"
}
growth: {
leadership: "Develops leadership capabilities"
perspective: "Broadens system perspective"
industry: "Stays current with industry trends"
vision: "Contributes to technical vision"
}
}
}
job staff_engineer {
name: "Staff Software Engineer"
requirements: {
technical: {
architecture: "Architects complex distributed systems"
strategy: "Drives technical strategy across projects"
oversight: "Provides technical oversight for critical initiatives"
decisions: "Makes high-impact architectural decisions"
}
project_execution: {
leadership: "Leads multi-team technical initiatives"
roadmap: "Defines technical roadmaps"
excellence: "Ensures technical excellence across projects"
balance: "Balances business needs with technical concerns"
}
problem_solving: {
challenges: "Solves organizational technical challenges"
architecture: "Creates scalable system architectures"
opportunities: "Identifies strategic technical opportunities"
governance: "Develops technical governance"
}
collaboration: {
influence: "Influences cross-team technical decisions"
consensus: "Builds consensus across engineering groups"
mentoring: "Mentors senior engineers"
communication: "Communicates technical vision effectively"
}
growth: {
innovation: "Drives technical innovation"
culture: "Shapes engineering culture"
industry: "Contributes to industry discussions"
leadership: "Develops organizational leadership skills"
}
}
}
job principal_engineer {
name: "Principal Software Engineer"
requirements: {
technical: {
vision: "Defines technical vision for multiple products"
strategy: "Creates multi-year technical strategies"
innovation: "Drives innovation in core architectures"
standards: "Establishes technical standards"
}
project_execution: {
leadership: "Leads organization-wide technical initiatives"
planning: "Drives strategic technical planning"
impact: "Makes decisions affecting multiple teams"
strategy: "Influences product strategy"
}
problem_solving: {
challenges: "Solves complex organizational challenges"
capabilities: "Creates new technical capabilities"
opportunities: "Identifies strategic opportunities"
practices: "Develops engineering best practices"
}
collaboration: {
influence: "Influences organization direction"
partnerships: "Builds strategic partnerships"
mentoring: "Mentors technical leaders"
representation: "Represents engineering organization"
}
growth: {
practice: "Advances state of practice"
knowledge: "Contributes to industry knowledge"
leadership: "Develops future technical leaders"
culture: "Shapes engineering culture"
}
}
}
matrix software_engineering {
name: "Software Engineering"
categories: {
technical: {
name: "Technical"
description: "Core technical and architectural capabilities"
}
project_execution: {
name: "Project Execution"
description: "Delivery and implementation of technical work"
}
problem_solving: {
name: "Problem Solving"
description: "Technical problem solving and system thinking"
}
collaboration: {
name: "Collaboration"
description: "Working with others and leadership"
}
growth: {
name: "Growth and Learning"
description: "Personal and professional development"
}
}
jobs: [
software_engineer_1,
software_engineer_2,
senior_engineer,
staff_engineer,
principal_engineer
]
}
member kevin_osei {
first_name: "Kevin"
last_name: "Osei"
job: software_engineer_2
email: "test-kevin-osei@hedge-ops.com"
}
member alex_rivera {
first_name: "Alex"
last_name: "Rivera"
email: "test-alex-rivera@hedge-ops.com"
}
People
The people section of the DSL is stored in ./people.ppl
and stores the user-specific
data for the app. It is not meant to be shared among people in the organization.
In this app, the user defines which member
they are via user
declaration and
which members they want to relate to as contacts.
Users also set an intention
for each contact
in order to remind them to
connect regularly with people.
User
Located in ./people.ppl
, this is the member
associated
with the user
. It is associated by sharing the same id
.
This exists so that the core
can be shared and the user
can still relate themselves to that core
.
If a user
is not defined, the workspace will not load.
Fields
intention
- (Optional) Anintention
block representing how the user wants to connect with themselves -Intention
Examples
Minimal
member alex_rivera {
first_name: "Alex"
last_name: "Rivera"
}
// same id as alex_rivera member, which means that Alex is
// the first person of this workspace (aka the user).
// no fields defined so no braces required
user alex_rivera
Full
member tara_johnson {
first_name: "Tara"
last_name: "Johnson"
}
// tara wants to reflect on this organization alone once a week
user tara_johnson {
intention: {
event_name: "Weekly Reflection"
recurrence: "FREQ=WEEKLY;INTERVAL=1;BYDAY=TU"
}
}
Contact
Located in ./people.ppl
, this is the member
that
the user
relates with in order to achieve their goals within the
organization. The contact
is associated with the member
by sharing the same id
.
This exists so the core
can be shared, different users
can relate to different people.
Fields
relationship
- (Required) What type of relationship thiscontact
is. Choices includestakeholder
,first_team
,direct_report
, andbase
-Identifier
intention
- (Optional) Anintention
block -Intention
Relationships
This app is prescriptive in helping people identify important relationships within an organization, and thus categorizes contacts into four groups. These are not official HR titles, just categories:
- Stakeholder: people who need for the
user
to deliver in order to succeed and will therefore advocate foruser
when they are not in the room. - First Team: usually the people who report to the
user
's boss, sharing in a broader mission than theuser
has. This team is important to track because in order to perform and grow, one has to be supportive and not competitive with their peers. - Direct Report: people who either report to the
user
or whom theuser
is leading or mentoring, when an individual contributor. Theuser
is likely responsible for the outcome of their work. - Base: this is every other important relationship, meant to ensure that there is a wider impact than just the team.
Examples
Minimal
member kevin_osei {
first_name: "Kevin"
last_name: "Osei"
}
// same id as kevin_osei member, which means that Kevin is
// a person the user of this workspace is relating to.
contact kevin_osei {
relationship: direct_report
}
Full
member jordan_kim {
first_name: "Jordan"
last_name: "Kim"
}
contact jordan_kim {
relationship: direct_report
intention: {
event_name: "1:1"
recurrence: "FREQ=WEEKLY;INTERVAL=1;BYDAY=FR"
}
}
Intention
An intention is set by the user
for themselves and their
contacts in order to maintain consistent connection.
The intention is essentially to connect with that person and journal that connection.
This is a child of both the user
and contact
, but we will document the fields and show examples here:
Fields
event_name
- (Required) The name of the event that the user wants to have with that person -String
recurrence
- (Required) The recurrence rule of the event -String
in RRule format
Examples
// alex wants to self reflect every Friday
user alex_rivera {
intention: {
event_name: "Weekly Reflection"
recurrence: "FREQ=WEEKLY;INTERVAL=1;BYDAY=FR"
}
}
// Alex wants to have a 1:1 with Kevin every Thursday
contact kevin_osei {
relationship: direct_report
intention: {
event_name: "1:1"
recurrence: "FREQ=WEEKLY;INTERVAL=1;BYDAY=TH"
}
}
Work
The policy of the app is set up with the core and people apps, but now it's time to do the work!
Types of Work
File Format
Each unit of work is
defined within a file with a .wrk
extension, straightforward and extensible. The file's name is the id
for that work.
Connections - Journaling
As the user
connects with themselves or other contacts, they will
journal those connections. This is located in ./work/[id]/journal
where [id]
is the identifier of the user
or contact
.
File Format
The file is saved as [YYYY-mm-dd]_[event_name_identifier].wrk
where the first part is the date of the connection
and the second part is the event name where spaces and other odd characters are converted into underscores.
Fields
event
- (Required) A block which includes details of theevent
, detailed below.observations
- (Optional, unlesssentiment
andcomments
are present) The factual elements of the connection. This should be descriptive of just the facts. -String
sentiment
- (Optional) How the user felt about the event. Choices includenegative
,neutral
, orpositive
-Identifier
comments
- (Optional) the textual reaction of the user, their feelings about the situation -String
event
name
- (Required) The name of the eventdate
- (Required) The date the connection occurred -String
inYYYY-MM-DD
formatrecurrence
- (Optional) when this event repeats, detailed below
recurrence
starting
- (Required) the date that the recurrence starts repeating -String
inYYYY-MM-DD
formatrepeats
- (Required) a recurrence string describing the schedule during which the event repeats.
repeats
has two main sections:
- Frequency and Interval. When interval is 1, the number can be omitted.
Examples:
daily
,weekly
,monthly
,yearly
,every 2 weeks
,every 3 days
- Predicate, which is specific to the type of frequency:
daily
For daily
there is no predicate.
Examples:
daily
every 3 days
weekly
For weekly
the predicate is the day of the week: on Friday
, on Saturday and Sunday
, on Monday, Wednesday and Friday
. If this is missing, the system
will assume that the schedule will repeat on the day of the week that the
starting date falls on.
Examples:
weekly
every 2 weeks
every 2 weeks on Friday
every 4 weeks on Monday, Wednesday and Friday
monthly
For monthly
the predicate can either list out the day of month or specify the position within the month that repeats.
For repeating on specific days of the month, list them out: 1st
, 1st and 15th
, 1st, 3rd and 10th
. This is optional and if it's
omitted the day of month is assumed to be the same day of month that the
starting date falls on.
For repeating on the position within the month, use an ordinal expression, which
has two parts: (1) The ordinal: first
, second
, third
, fourth
, fifth
,
next to last
, last
and the day specification, which is a day of the week
(Sunday
, Monday
) or one of day
, weekday
, or weekend day
.
Examples:
Specific days of the month:
monthly on the 1st and 15th
every 2 months on the 1st
Position within the month:
monthly on the first Sunday
monthly on the last day
every 3 months on the first Friday
yearly
For yearly
the predicate lists out the months as above, with in
as a
preposition: in January
, in January and February
, in January, February and March
. Just as above, if the month is not there the system assumes that the
month is the same month the starting date falls within.
The yearly also can have the ordinal predicate, as specified above.
Examples:
yearly
yearly in January
yearly in May and November
yearly on the last Sunday
yearly in May on the last day
every 3 years
every 4 years on the first Tuesday
Examples
Upcoming
// located in ./work/tara_johnson/journal/2025-01-23_lunch.wrk
// Alex (the user) will have lunch with Tara on January 23, 2025.
// After the lunch he'll come back and write his observations and reactions
// about the upcoming connection.
event: {
name: "Lunch"
date: "2025-01-23"
}
Recurring
event: {
name: "Lunch"
date: "2025-01-23"
recurring: {
starting: "2025-01-23"
repeats: "every 2 weeks"
}
}
Journaled
// located in ./work/tara_johnson/journal/2025-01-23_lunch.wrk
// Alex (the user) had lunch with Tara on January 23, 2025.
// He wrote down the important facts of their interaction
// He also wrote down his feelings about the ineraction
event: {
name: "Lunch"
date: "2025-01-23"
}
observations: """
Talked about Project Gravy which is late
Tara has helped Kevin deliver on the containers feature.
"""
sentiment: positive
comments: """
Tara does struggle with some things but I'm impressed by her being
a team player, especially with Kevin.
"""
Workspace Template
Once someone in your organization has created a workspace, there's no need to create a new one from scratch. You can share it with others in order to reuse shared concepts. Here's how you can do that:
-
The new user will create a new nested folder on their computer called
people/<workspace-name>
, for examplepeople/wincorp
. -
You, the original workspace creator, will copy your
core.ppl
file andassets
folder with everything in it from your workspace folder and share it with them. -
The new user will put the shared
core.ppl
file andassets/*
folder and contents in their newly createdpeople
folder on their computer. -
This new user will find the
member
associated with them in thecore.ppl
and copy their member ID. For example, if Kevin Osei was creating auser
for himself, he would find this block incore.ppl
and copykevin_osei
:member kevin_osei { first_name: "Kevin" last_name: "Osei" job: software_engineer_2 email: "test-kevin-osei@wincorp.com" }
-
The new user will then create their own
people.ppl
file inside theirpeople/<workspace-name>
folder. -
Inside that file, they will create their user by adding a
user
block that uses their ID from above. For example, Kevin Osei would type this in hispeople.ppl
file:user kevin_osei {}
-
This new user can now open this workspace in the People Work app by going to File > Open Workspace > Open Existing Workspace, and clicking on their newly created workspace folder.
Configuration
People Work is meant to be configuration-free while also providing easy out-of-the-box configuration offers that developers are accustomed to using.
There are two main configuration files:
~/.config/people/config.toml
- configuration that is static and can be saved in adotfiles
repo.~/.local/state/people/state.toml
- configuration that is related to how the user is using the app and is machine-specific.
Application Configuration
This refers to global configuration for the user that can be saved in a dotfiles
repo, does not change very often, is not sensitive, and is located
in ~/.config/people/config.toml
. The following properties are supported:
Default Workspaces Parent Directory
- Value -
default_workspaces_parent
of typepath
. - Default -
~/Documents/People
The location of the parent folder that is used when a new workspace is created. The user might want to change this when they are using a synced folder location.
Example:
default_workspaces_parent = "~/Synced/Documents/People"
Workspaces
- Value:
workspaces
of an array of paths - Default:
[]
(empty array)
The location workspaces that the user can switch between in the app.
If any of the directories listed here no longer exist, they will be removed and the config file will be updated. This also applies to the current workspace in the state config.
Example:
workspaces = [
"~/Docuemnts/People/My Corp",
"~/Docuemnts/People/Local Tech Community"
]
State
This is only for reference; when you use the app it will update these values.
Current Workspace
- Value:
current_workspace
that is a path - Default: none
The location workspaces that the user is currently working on. The app will automatically open to this location.
Example:
current_workspace = "~/Docuemnts/People/My Corp"