POM is a lightweight method for keeping a project's operating memory alive by connecting sources, code, mockups, wiki pages, decisions, verifiable tasks, roadmap context, and official documentation.
This README is POM's canonical entry point and operating overview. Detailed procedures live in the repository's canonical files: AGENTS.MD, skills/, prompts/, templates/, and scripts/.
POM is designed to be reused on new or existing projects. It does not impose a single application structure and does not assume that every project has mockups, source code, tests, or official docs. For existing projects, POM should first map the current structure in pom.config.json; migration to canonical folders is a later explicit decision, not a prerequisite.
Version: 0.1.0
Release notes: see CHANGELOG.md.
POM - Project Operating Memory is created and maintained by Fabio Malpezzi.
Website: https://www.improveandmanage.com/
Special thanks to Andrej Karpathy for the LLM Wiki pattern that inspired POM's persistent wiki approach.
For a reader-friendly explanation of POM's purpose, tools, adoption levels, skills, and recommendations, see:
These guides are explanatory or generated reader views, not normative replacements. Operational rules remain in README.md, AGENTS.MD, prompts/, skills/, templates/, scripts/, and the source Markdown under wiki/.
Use the smallest workflow that matches your situation:
| Situation | Start Here |
|---|---|
| Ambiguous request or artifact | skills/clarify.md |
| New project | skills/seed.md |
| Existing project | skills/adopt.md |
| External repository you do not own | Overlay mode in specs/SPEC-0004-external-project-overlay.md |
| Resume after a pause | skills/pulse.md |
| Ask or maintain the wiki | skills/wiki.md |
| Render the wiki reader | npm run pom:wiki:render |
| Browse, search, and annotate the project locally | POM Project Reader server |
| Extend POM | skills/extend.md |
| Reduce method bloat | skills/prune.md |
| Diagnose a POM problem | skills/diagnose.md |
| Rework a patch around the intended final shape | skills/zero-tech-debt.md |
| Challenge a spec or decision before closure | skills/challenge.md |
| Defer work without implementing | skills/defer.md |
| Refresh or sync POM in a project | skills/sync.md |
| See available commands | npm run pom:help |
Once POM is installed, tell the agent what you need. The agent reads the skill card, then the linked prompt, then the relevant templates.
# Bootstrap a new project
Read pom/skills/seed.md and set up POM for this project.
# Build the wiki from existing sources
Read pom/skills/wiki.md in build mode and create the wiki.
# Generate the static wiki reader
npm run pom:wiki:render
# Open the static wiki reader
wiki.html
# Open the local Project Reader server
node experiments/wiki-agent-orchestration/mini-ui/server.mjs --port 4173
# Resume after a pause
Read pom/skills/pulse.md and update PROJECT_STATE.md.
# Turn a spec into tasks
Read pom/skills/plan.md and create a task plan from specs/my-feature.md.
# Defer future work
Read pom/skills/defer.md and park this topic without implementing it.
# Rework a patch around the intended final shape
Read pom/skills/zero-tech-debt.md and reshape the current change before closure.
# Challenge a non-code spec or decision
Read pom/skills/challenge.md and run an adversarial thesis/antithesis review of specs/my-feature.md.
# End-of-session handoff
Read pom/skills/handoff.md and update the project state.
See examples/agent-conversations.md for more detailed interaction examples.
The POM Project Reader is an experimental local web server for browsing a repository without turning generated HTML into a new source of authority. By default, it uses the current working directory as the project root and port 4173; pass --root or --dir and --port when you want to choose them explicitly.
Project-wide content search requires rg from ripgrep. Annotation files default to experiments/wiki-agent-orchestration/evidence/annotations/ under the project root; pass --annotations-dir to use a different working directory for annotation handoff files.
From this POM Source repository:
node experiments/wiki-agent-orchestration/mini-ui/server.mjs --port 4173From a target project where POM is installed under pom/:
node pom/experiments/wiki-agent-orchestration/mini-ui/server.mjs --port 4173Explicit form:
node pom/experiments/wiki-agent-orchestration/mini-ui/server.mjs --port 4173 --root . --annotations-dir .pom-reader/annotationsThen open:
http://127.0.0.1:4173
The reader starts from wiki/index.md when the project has a wiki. If the project has no wiki index, it shows a generated POM Project Reader entry page and still exposes project documentation and source files through an explicit allowlist.
When pom.config.json exists, the reader uses it to classify configured project roots. For example, documentation.officialRoot and documentation.existingRoots become project documents, decisions.root becomes decisions, taskPlans.root becomes task plans, analysis.root becomes analysis, source.roots become source, and tests.root becomes tests. It also respects generated-output exclusions from artifactPolicy.generated in navigation and search. If the config is missing, the reader keeps the built-in allowlist. If the config exists but is invalid JSON, the server fails loudly instead of guessing. The UI shows whether it is using pom.config.json or the built-in roots.
It can show and search:
- wiki pages, README, context, docs, specs, decisions, task plans, prompts, skills, templates, examples, selected experiment files, scripts, tests,
bootstrap-pom.mjs, andpackage.json; - thematic navigation and project-tree navigation;
- collapsible or pinned navigation and annotation side panels;
- project-wide
rgsearch with optional regex mode; - search inside the open file, with optional regex mode;
- a responsive document surface that keeps prose readable while giving code blocks and tables more room on large screens;
- Markdown tables, fixed-width text blocks, syntax-highlighted code, source line numbers where they are useful, and English/Italian interface labels.
- local safety guards: rendering rejects files above 1 MB and binary-looking files, while project search skips files above 1 MB.
Annotations are file-based. The UI saves JSON work files under the configured annotation directory. Treat this as runtime evidence and keep it out of commits unless the project intentionally wants to archive an annotation. If you choose a custom annotation directory, add it to the target project's ignore rules.
The annotation panel has "New note", "In progress", and "Processed" tabs. It can send selected document text into a note, show the JSON work file on demand, and reopen the target document when an annotation is selected. Browser-based source editing is not part of the current workflow.
The server binds to 127.0.0.1 and sends restrictive browser security headers. It is still a local repository browser; do not expose it on a shared network without a separate threat model.
A coding agent can read the next open annotation from the same project root:
node experiments/wiki-agent-orchestration/wiki-tools.mjs claim-next --by codexWhen the server uses a custom annotation directory, pass the same directory to the CLI:
node experiments/wiki-agent-orchestration/wiki-tools.mjs claim-next --by codex --annotations-dir .pom-reader/annotationsWhen the CLI is being used from an installed pom/ folder, prefix the script path with pom/. The UI does not talk directly to an AI agent; the annotation file is the handoff artifact, and durable document changes still need a separate reviewed edit.
Requirements: Node.js ≥22.6 (for TypeScript script execution via --experimental-strip-types). Git required.
Download and run the bootstrap script from the target project root:
curl -fsSL https://raw.githubusercontent.com/FabioMalpezzi/pom/main/bootstrap-pom.mjs -o bootstrap-pom.mjs
node bootstrap-pom.mjs --preset ownedDo not install POM by running git clone https://github.com/FabioMalpezzi/pom.git . in a project root. This repository is the POM Source. The bootstrap is the supported install path because it keeps the reusable method under pom/ and leaves project-owned files at the target project root.
If your goal is to improve POM itself, clone this repository as its own working repository and do not run the bootstrap. Use the source repository commands such as npm run pom:lint, npm run pom:test, and npm run pom:wiki:render.
When asking an AI agent to install this method, say POM - Project Operating Memory from FabioMalpezzi/pom and ask it to run the bootstrap from the target project root. That wording distinguishes POM from Maven pom.xml, Page Object Model, and other common meanings.
Suggested AI-agent prompt:
Install POM - Project Operating Memory from https://github.com/FabioMalpezzi/pom in this target project. Treat that repository's README as the installation authority for this turn. Fetch or read the README first, then follow its Installation section. Do not use Maven, Page Object Model, or a remembered POM workflow. Do not clone the repository into the project root; use the bootstrap from the target project root. If I have not stated a preset, ask me to choose one of owned, team, overlay, or minimal.
If you already know the preset, include it in the prompt, for example: Use preset owned.
Do not pipe a remote bootstrap script directly into node. Download it first, then inspect it or verify it before running.
For environments that require a pinned and checked install, prefer a tag or commit URL and verify the bootstrap checksum before execution:
POM_REF=main
curl -fsSL "https://raw.githubusercontent.com/FabioMalpezzi/pom/${POM_REF}/bootstrap-pom.mjs" -o bootstrap-pom.mjs
curl -fsSL "https://raw.githubusercontent.com/FabioMalpezzi/pom/${POM_REF}/checksums/bootstrap-pom.mjs.sha256" -o bootstrap-pom.mjs.sha256
shasum -a 256 -c bootstrap-pom.mjs.sha256
node bootstrap-pom.mjs --preset ownedUse main only when you intentionally want the current development line. For repeatable adoption, set POM_REF to a release tag or immutable commit and use the checksum published with that same ref.
Choose the preset that matches your relationship to the repository:
| Preset | Use when | Meaning |
|---|---|---|
owned |
The project is yours | POM may become project governance when useful. |
team |
The project is shared with a team | POM must preserve shared conventions unless explicitly changed. |
overlay |
The repository belongs to an external upstream | POM is local understanding memory only. |
minimal |
You want only the smallest local setup | POM starts with minimal memory and no ownership assumption. |
Running bootstrap-pom.mjs without a preset prints this guide and exits. POM does not guess ownership during first install.
Use --lang it|en only when you want to force the language of CLI guidance.
After bootstrap has installed pom/, for agent-driven setup on a new project, ask:
Read pom/skills/seed.md and set up POM for this project.
After bootstrap has installed pom/, for agent-driven adoption in an existing repository, ask:
Read pom/skills/adopt.md and adopt POM without changing the existing structure.
For a cloned repository you do not own, prefer overlay mode:
node bootstrap-pom.mjs --preset overlayThen ask the agent to read the overlay rules before adding project memory:
Read pom/specs/SPEC-0004-external-project-overlay.md and use POM as a local understanding overlay, not as project governance.
In overlay mode, POM governs the operator's understanding of the project. It must not impose POM conventions on upstream docs/, tests/, ADRs, source layout, release process, or pull-request contents.
The bootstrap script:
- clones POM into
pom/(or pulls if it already exists); - runs the installer using the selected preset;
- initializes Git in the target project root when the target is not already inside a Git worktree;
- lets advanced users choose an adoption profile directly (minimal, wiki, decisions, full, adopt, refresh, custom);
- updates the POM section in every existing supported agent instruction file, or creates
AGENTS.mdif none exists; - creates
package.jsonscripts,pom-update.mjs,pom.config.json, and governance folders based on the chosen profile. - installs or updates the Git pre-commit hook with POM checks when the target project root is the Git worktree root.
You can also pass a profile directly for advanced use:
node bootstrap-pom.mjs --profile fullFor existing repositories, the presets are the normal path:
node bootstrap-pom.mjs --preset owned
node bootstrap-pom.mjs --preset team
node bootstrap-pom.mjs --preset overlayYou can still pass ownership explicitly when the agent or user already knows the relationship:
node bootstrap-pom.mjs --profile adopt --ownership owned
node bootstrap-pom.mjs --profile adopt --ownership team
node bootstrap-pom.mjs --profile adopt --ownership external_overlayThe same option is available after POM is installed:
npm run pom:init -- --preset overlayFor normal manual updates from a project that already has POM installed:
npm run pom:update
git diffpom:update updates pom/, refreshes the POM section in every existing supported agent instruction file, updates package scripts and the pre-commit hook, then runs pom:lint when available. It supports both Git-managed POM installs and clean vendored pom/ copies. It does not change pom.config.json, project documents, wiki, decisions, or project-owned templates outside pom/.
pom:update also does not change adoption mode. If called with --preset, --profile, or --ownership, it stops and tells you to use pom:init instead. Changing mode is a governance decision, not a framework update.
If pom/ has local changes, pom:update stops and suggests pom/skills/sync.md instead of overwriting them. For vendored copies, unrelated parent-project changes outside pom/ do not block the update.
For agent-driven updates, use the sync skill:
Read pom/skills/sync.md and refresh this project's POM installation.
If the project does not have pom:update yet, install the current updater once:
curl -fsSL https://raw.githubusercontent.com/FabioMalpezzi/pom/main/bootstrap-pom.mjs -o bootstrap-pom.mjs
node bootstrap-pom.mjs --profile refreshIf POM is already installed, pom/ is clean, and package.json has the scripts, you can also refresh only generated sections with:
npm run pom:init -- --profile refreshThat command is an advanced convenience path. It does not replace pom:update when POM itself may need to be pulled first.
After installation, show the command guide with:
npm run pom:helpPrints the command reference and skill index. Always exits immediately — no interactive input required.
Supported instruction targets are deliberately conservative:
- existing root files:
AGENTS.md,AGENTS.MD,agents.md,CLAUDE.md,GEMINI.md,CONVENTIONS.md,.cursorrules,.clinerules,.windsurfrules; - existing nested files:
.github/copilot-instructions.md,.junie/guidelines.md,.junie/instructions.md,.junie/AGENTS.md; - existing rule folders, where POM creates or updates a dedicated file:
.claude/rules/pom.md,.github/instructions/pom.instructions.md,.cursor/rules/pom.mdc,.windsurf/rules/pom.md,.kiro/steering/pom.md,.continue/rules/pom.md,.roo/rules/pom.md,.clinerules/pom.md.
POM does not create tool-specific folders just because the tool exists. It only writes into a tool-specific folder when that folder is already part of the project.
For Claude Code, .claude/agents/pom-post-action-validator.md is optional. The installer creates or updates it only when .claude/ already exists. If .claude/ is missing, the installer prints the exact mkdir -p .claude and npm run pom:init ... commands to enable the helper with the same install mode.
For OpenAI Codex, AGENTS.md is the project instruction target. The equivalent post-action audit is the generic pom/skills/validate.md skill and its canonical prompt pom/prompts/18-post-action-validator.md; no Claude-specific wrapper is required.
Use overlay mode when the repository is cloned from an upstream you do not own and POM is needed to understand, audit, or prepare a limited contribution.
Overlay mode is different from adoption:
| Mode | What POM governs |
|---|---|
| Adoption | the project's operating method |
| Overlay | the operator's local understanding of someone else's project |
Overlay mode should keep upstream structures authoritative:
- upstream
docs/remain upstream documentation, not POM-governed docs; - upstream
tests/remain upstream test layout, not POM-governed test structure; - upstream agent instruction files should be preserved unless local agent guidance is intentionally added;
- local wiki pages are working notes for understanding architecture, entrypoints, modules, tests, conventions, risks, and open questions;
- before opening a PR, POM overlay artifacts must stay out of the contribution unless the upstream project explicitly wants them.
Recommended Git posture:
- keep the overlay in its own branch or, better, in a separate Git worktree;
- do actual upstream contribution work on a separate feature branch;
- do not merge the overlay branch into the contribution branch;
- transfer only selected non-POM changes with a patch, file checkout, or
git cherry-pick -nof commits that contain no POM artifacts.
See specs/SPEC-0004-external-project-overlay.md for the documented mode and future implementation requirements.
If you customized or translated templates, keep them outside pom/ before refreshing, for example:
project-templates/
ADR_TEMPLATE.md
WIKI_PAGE_TEMPLATE.md
PROJECT_STATE_TEMPLATE.md
Then point pom.config.json to those project-owned templates:
"templates": {
"adr": "project-templates/ADR_TEMPLATE.md",
"wikiPage": "project-templates/WIKI_PAGE_TEMPLATE.md",
"projectState": "project-templates/PROJECT_STATE_TEMPLATE.md"
}Template paths in pom.config.json are relative to the target project root, where pom.config.json, agent instruction files, package.json, and pom/ live. For example, project-templates/ADR_TEMPLATE.md means <project-root>/project-templates/ADR_TEMPLATE.md, not <project-root>/pom/project-templates/ADR_TEMPLATE.md.
Do not customize files directly under pom/: updates may overwrite them or create Git conflicts.
The bootstrap itself requires only Node ≥20. The installer it launches requires Node ≥22.6.
Important: POM must live in a subfolder (typically pom/), not at the project root. Cloning POM directly into the root would overwrite the project's README.md, AGENTS.MD, and package.json, and break all internal path references.
# Option A: Git submodule (stays updatable)
git submodule add https://github.com/FabioMalpezzi/pom.git pom
# Option B: Simple copy
cp -r /path/to/pom ./pomThen run the installer:
node --experimental-strip-types pom/scripts/install-pom.tsIn the common Git-managed install, pom/ is a full checkout of the POM Source and may contain its own .git, README.md, AGENTS.MD, bootstrap-pom.mjs, and package.json. That is expected. The wrong layout is POM Source files directly at the target project root.
On a new project, the root may initially contain only pom/, agent instructions, package.json, pom-update.mjs, and pom.config.json. That is a valid day-zero state: create PROJECT_STATE.md, CURRENT_PLAN.md, tasks/, analysis/, docs/, wiki/, or the configured decisions root only when the selected adoption profile enables them or current work needs them.
If a new project has no application infrastructure yet, POM must not infer the stack, source layout, package manager, deployment model, database, authentication system, test framework, or hosting strategy on its own. Treat infrastructure as a project decision: ask the user how they want it realized, or create an approved Open Discussion or analysis note for the alternatives, before scaffolding code or committing to a technical structure.
my-project/
pom/ <- POM method (this repository)
.git/ <- present in Git-managed installs
prompts/
skills/
templates/
scripts/
AGENTS.md <- project agent instructions, when used (references pom/)
CLAUDE.md <- also updated when already present
pom.config.json <- project-specific config
wiki.html <- shortcut to the generated wiki reader, if wiki profile enabled
wiki/ <- if wiki profile enabled
decisions/ <- default decisions root, if decisions profile enabled
...
If the project does not use npm, copy the POM section manually into every agent instruction file used by the project:
| Agent | Instructions file | What to do |
|---|---|---|
| OpenAI Codex | AGENTS.md |
Copy pom/templates/AGENTS_POM_SECTION_TEMPLATE.md into AGENTS.md |
| Claude Code | CLAUDE.md |
Copy pom/templates/AGENTS_POM_SECTION_TEMPLATE.md into CLAUDE.md |
| Gemini | GEMINI.md |
Copy pom/templates/AGENTS_POM_SECTION_TEMPLATE.md into GEMINI.md |
| GitHub Copilot | .github/copilot-instructions.md or .github/instructions/pom.instructions.md |
Copy the template content into the project instructions |
| Cursor | .cursor/rules/pom.mdc or .cursorrules |
Copy the template content into a project rule |
| Windsurf | .windsurf/rules/pom.md, .windsurfrules, or AGENTS.md |
Copy the template content into a project rule |
| Kiro | .kiro/steering/pom.md |
Copy the template content as a steering file |
| Junie | .junie/AGENTS.md or .junie/guidelines.md |
Copy the template content into the project guidelines |
| Cline / Roo / Continue | tool-specific rules file or folder | Copy the template content into a POM-specific rule file |
| Other agents | Agent-specific config | Adapt the template to the agent's instructions format |
Use the skill that matches your situation (see Quickstart table above). The agent will read the skill card, then the linked prompt, then the relevant templates.
pom:init initializes Git in the target project root when the target is not already inside a Git worktree. When the target project root is the Git worktree root, it installs a managed POM block in the resolved Git pre-commit hook path.
If the target project is a subdirectory inside a larger Git worktree, pom:init does not create a nested repository and does not install a hook automatically. Install POM from the Git root, or adapt the hook manually so it runs the target project's npm run pom:lint from the correct directory.
The hook is agent-neutral. It works for Claude Code, Codex, and any other workflow because it only runs local project commands.
The hook:
- runs
npm run pom:lint; - blocks the commit if lint fails;
- if
PROJECT_STATE.mdexists and governed project-memory files are staged, prints a non-blocking reminder to update it when the restart context changed.
The hook does not synthesize or rewrite PROJECT_STATE.md: that remains the agent's responsibility, because it requires project understanding. Claude Code can use the optional pom-post-action-validator agent when installed; Codex can use pom/skills/validate.md for the same read-only audit.
Update PROJECT_STATE.md when the project restart context changes:
- substantial ADR change;
- substantial spec change;
- roadmap, priority, dependency, or current-plan change;
- important task/phase closed;
- new relevant risk, blocker, or open decision;
- explicit end-of-session or end-of-day handoff request.
Do not update it for typo fixes, regenerated indexes, small link fixes, or changes that do not affect how the next session should restart.
POM's wiki model is inspired by Andrej Karpathy's LLM Wiki pattern, published in the karpathy/llm-wiki.md gist:
https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f
The local reference copy of the method is in WIKI_METHOD.md.
The gist describes a Markdown wiki maintained incrementally by an LLM, with raw sources, wiki pages, an operating schema, ingest/query/lint operations, an index, and a log.
POM is documented in English for portability.
When applying POM to a project, the agent must use the project/user language for:
- conversation;
- generated documentation;
- wiki pages;
- ADRs;
- task plans;
- project state;
- reports.
If the project already has a dominant documentation language, follow it. If the user asks for a different language, follow the user. If sources are multilingual, preserve source titles and quoted terms, but write synthesis in the project/user language.
This repository has its own AGENTS.MD. That file governs work on the POM repository itself. Do not copy it verbatim into target projects.
For a target project, use pom/templates/AGENTS_POM_SECTION_TEMPLATE.md as the source for the project's agent instructions. The installer updates every existing supported agent instruction target so different coding agents see the same POM rules. If none exists, it creates AGENTS.md.
Supported installation styles:
- copy POM into the target project as a
pom/folder; - add POM as a Git submodule or subtree under
pom/; - keep POM as an external reference and copy only the needed templates/prompts.
pom/templates/POM_CONFIG_TEMPLATE.json assumes the common installation style where POM lives in the target project as pom/, so template paths point to pom/templates/.... If you install POM somewhere else, adapt those paths in the target project's pom.config.json.
POM does not use one universal source of truth. It uses source authority by domain:
| Question | Authoritative Source |
|---|---|
| What does the system currently do? | code and tests, when present |
| What do we currently know about the project? | wiki/ |
| Why did we decide this? | configured decisions root (decisions.root, default decisions/) |
| What analysis supports or challenges a choice? | analysis/ |
| What is still desiderata, hypotheses, or unresolved discussion? | Open Discussion or analysis/, not implementation authority |
| What does the intended experience show? | mockups/, when present |
| What can be shared as official documentation? | docs/, when present |
| Where do I restart after a pause? | PROJECT_STATE.md or current plan |
When sources diverge, the divergence must not be hidden. It must be made visible, analyzed, and resolved with a decision when needed.
POM separates source authority from edit permission. Before changing a governed artifact, check project config or the file itself: editable may be changed directly when the source authority supports it; approvalRequired needs explicit user approval; generated must be regenerated from its source; historical should not be rewritten after closure.
Five operating rules apply to every project that uses POM, independently of the adoption profile. They are also reproduced in AGENTS.md so the agent reads them at start of session.
Rules for chat messages to the user.
- Use the user's language naturally. No hybrid forms when an idiomatic phrase exists.
- Project labels are codes, not words. Administrative labels (spec numbers, ADR identifiers, decision IDs, phase numbers) are archive codes. On first occurrence in the turn, state in plain words what the label refers to. Do not chain more than two such labels in a single sentence. Do not let the label replace the noun ("decide what to do with the finalizers", not "close D10.4").
- No abstract placeholders. Forbidden in chat: "I created file X that does Y", "apply rule Z to field W". Real names go in full. Placeholders only in code or formal templates.
- Summaries in full sentences. End-of-task recaps describe what was done and what is still open in normal sentences, not in stacks of acronyms.
Project documentation must stay lean and load-bearing. Its history lives in Git, not in the document text.
- Update before creating. If an existing document covers the topic, rewrite it instead of adding a new parallel one. Version history is in Git.
- No project log inside the docs. Specs, ADRs, task plans and wikis describe current state and live decisions, not the chronicle of edits. The chronicle lives in Git.
- If a project log is needed, create it explicitly. Dedicated file, short entries "date + document + one-line change". Adopting it is an explicit choice taken with the user.
- Fewer documents, more consistency. Before creating a new document, check whether the content fits in an existing one.
- Optimize for the next safe step. When the right document is unclear, write the smallest useful note where the next reader or agent will need it before acting.
Design and analysis must rely on the current state of code and documents, never on a recollection of them.
- Read before designing. Open the actual file before proposing changes, summarizing behavior, or referencing decisions.
- Use the domain glossary. Read
CONTEXT.mdbefore design, refactoring, or governance changes, and use its terms in new prompts, templates, specs, and code comments. - Verify before citing. A note or memory saying "X exists" or "spec Y says Z" is a claim to verify against the repository, not a fact.
- Declare gaps. If the artifact you expected cannot be found, say so. Do not fill the gap with assumptions.
- No reconstruction from memory. Describing the current content or behavior of a file requires reading it now.
Source files should remain readable and verifiable by automated tooling. POM enforces a structural limit on file size; surrounding tooling is recommended, not imposed.
- Hard cap at 1000 lines. No code file should exceed 1000 lines. Above that, split it along a natural seam. This is a POM rule.
- Aim for under 800. Treat 800 lines as the working target.
- Cap applies to hand-written source. Generated code, large fixtures, and data dumps are exempt.
- Recommended: configure a linter. POM does not bundle one. Target projects are encouraged to add a language-appropriate linter and run it as part of the routine cycle.
- Recommended: configure a type checker. When the language and environment support it, target projects are encouraged to add a type checker alongside the linter.
Code complexity should stay within the conventions of the language and the architecture chosen for the project. POM proposes the guardrails below; the target project owns their installation and threshold tuning.
- Recommended: configure a complexity checker. Suggested tools include ESLint
complexity/sonarjs,gocyclo,radon,pmd,checkstyle. When adopted, prefer binding thresholds over advisory ones so they actually shape merges. - Architectural boundaries are limits too. When the project adopts a style (layered, hexagonal, clean, MVC), respect its layer boundaries, allowed dependencies, and module sizes.
- Refactor before exception. When a unit crosses the threshold, split it before merging. Bypassing the limit requires an explicit decision recorded in an ADR.
- Tests are not exempt. Excessive complexity in tests indicates a design problem in the code; address the cause.
CI is optional. POM runs entirely on local commands and the pre-commit hook; nothing breaks if a project never sets up a remote pipeline. When the target project does want CI, see pom/templates/CI_GUIDE_TEMPLATE.md for provider-agnostic snippets (GitHub Actions, GitLab CI, CircleCI, generic shell). POM does not install or generate workflow files; the template is a starting point the project copies and adapts.
POM assumes Git as an operational prerequisite when the project must be governed over time.
Rules:
- Git keeps fine-grained history for specs, ADRs, wiki pages, and code;
- do not duplicate detailed history inside ADRs, specs, or
PROJECT_STATE.md; - check
git statusbefore major reorganizations; - if the project is not under Git, initialize Git before applying POM structurally; the installer does this automatically during setup;
- after structural changes, run available lint/tests and create a descriptive commit.
Specs, task plans, ADRs, wiki pages, and other documentation can be committed directly to the main branch. They are governed documents, not executable code, and do not risk breaking the build.
Create a feature branch (feat/<topic>) only when the first task plan step modifies executable code, configuration, prompts consumed at runtime, or test fixtures. The branch isolates changes that could break the build or alter runtime behavior.
| Artifact | Branch needed? |
|---|---|
| Spec, task plan, ADR, wiki page, analysis | No — commit on main |
| Source code, runtime config, prompts, test fixtures | Yes — feature branch |
| Experiment or spike | Yes — exp/<topic> or temporary branch |
Specs are living documents: edit them directly and let Git keep fine-grained history.
ADRs represent decisions. If a decision changes substantially, do not simply rewrite the previous ADR. Create a new ADR that supersedes or replaces it, or update the existing ADR only when the change is administrative. Use Open Discussion or analysis for undecided alternatives; do not create Draft ADRs for options that have not been chosen.
Rules:
- minor spec/ADR change: edit directly + Git;
- substantial spec change: update the spec and evaluate tasks/review;
- changed decision: create a new or replacement ADR;
- do not maintain manual changelogs inside specs/ADRs unless explicitly requested;
- every ADR should expose
CategoryandAreain the opening metadata table; - lint generates an ADR index from those metadata fields as a search/navigation view, not as a second source of truth;
- do not introduce workflow states in ADRs: if a document is in the configured decisions root, it is a valid decision; replacements are handled through
ReplacesandReplaced by.
Experiments must remain separate from the stable codebase until evaluated. Use branch exp/<topic>, /tmp, or experiments/<topic>/ depending on the case. Consolidate only after evaluation.
For risky or broad experiments, prefer a Git worktree on an exp/<topic> branch so the main working tree stays clean. Keep trial dependencies, environment files, service config, generated output, and external repositories isolated from stable source unless adoption is approved. Stable source must not import from experiments/; use lint/type/build guardrails where the project already has them.
See prompts/09-run-temporary-experiment.md for the full workflow.
POM treats the wiki as a persistent, cumulative artifact, not a temporary RAG index. The agent should not rediscover everything from scratch on every question: it should maintain structured, interlinked, current knowledge.
Rules:
- the wiki contains the current synthesis, not the full history of decisions;
- sources, code, mockups, and analysis feed the wiki;
- the configured decisions root keeps decision rationale and decision history;
wiki/index.mdis the content map;wiki/log.mdis the append-only chronological register and is not rendered as a reader page;npm run pom:wiki:rendergenerateswiki/_site/as a static reader view;wiki.htmlat the project root is the stable human shortcut to the generated reader when the wiki is enabled, and explains how to enable or generate the wiki when the reader is missing;- a useful answer or analysis can become a new wiki page;
- every relevant update should check contradictions, stale claims, missing links, and orphan pages.
The generated reader is derived output. It is useful for browsing and search, but Markdown remains the canonical Operating Memory. pom:lint regenerates wiki/_site/ at the end only when Git reports changed Markdown pages under wiki/; npm run pom:wiki:render remains available for explicit regeneration.
Wiki pages may define optional YAML frontmatter with navTitle when the H1 is too long for reader navigation. The reader uses navTitle in side navigation, breadcrumbs, and previous/next links, while keeping the full H1 as the page title and search text. Omit navTitle when the H1 is already short enough.
Mermaid rendering is opt-in. By default, the generated reader does not load Mermaid or any external CDN; it shows Mermaid blocks as readable source. If a project passes --mermaid-runtime with a remote URL, the generated reader will fetch that module in the browser. Offline or sensitive environments should use no runtime or a local vendored runtime. POM does not add Subresource Integrity for remote Mermaid modules.
flowchart LR
S[Sources, code, docs, analysis, conversation] --> W[Update wiki Markdown]
W --> L[npm run pom:lint]
L -->|wiki/*.md changed| R[Regenerate wiki/_site]
L -->|no wiki change| O[Governance check only]
R --> H[Open root wiki.html]
W --> G[Commit Markdown and generated reader]
R --> G
Operational rules:
- edit
wiki/*.md, notwiki/_site/*.html; - run
npm run pom:lintafter wiki changes; - let lint regenerate
wiki/_site/when Git reports changed wiki Markdown; - use
npm run pom:wiki:renderwhen an explicit reader refresh is needed; - commit Markdown and regenerated reader output together when the reader output is tracked.
Inputs / Code / Mockups / Analysis / Conversation
-> Wiki
-> Decisions
-> Delivery Plan
-> Docs
-> Project State
Small projects can start with a minimal POM setup. Mockups, official docs, structured tests, and extended lint are not required at the beginning.
Recommended minimum:
agent instruction file or rule
PROJECT_STATE.md
wiki/index.md
wiki/log.md
configured decisions root (default `decisions/`)
optional pom.config.json
Rules:
- use
skills/seed.mdfor a new project orskills/adopt.mdfor an existing project; - create only the directories that are actually useful;
- use
PROJECT_STATE.mdas restart memory; - use
wiki/only when there is knowledge worth maintaining over time; - use ADRs only for decisions that change direction or constrain the project;
- add lint, mockups, docs, tests, or an extended roadmap when the project grows.
The hierarchy is logical, not physical. It organizes work, not folders. Verification happens at every level, not only at the bottom.
For small projects, use the short form:
Task (closes with integration tests / single-feature E2E)
-> Step (closes with atomic verification: unit test, lint, check)
For larger or multi-stream projects, use the full hierarchy:
Roadmap
-> Phase (closes with acceptance review)
-> Workstream (closes with cross-functional E2E / user-flow tests)
-> Task (closes with integration tests / single-feature E2E)
-> Step (closes with atomic verification: unit test, lint, check)
Place E2E and user-flow tests at Task or Workstream level, not at Step level. Step-level verification covers atomic checks only.
Use Roadmap only when the project needs multi-phase direction or coordination across multiple streams. Do not force all levels into small work items.
A spec, task, or ADR cannot be marked Complete/Accepted without passing the completion verification gate. This gate is mandatory and automatic: the agent executes it when marking work as Complete, without asking.
Verification procedure:
- Goal-backward check (first): verify the declared goal is actually achieved — "what must be TRUE for this goal to be met?" — before checking tests or theses. If the goal is not met, the work cannot be Complete regardless of checkbox status.
- Technical work (with code): at least 2 positive scenario tests based on real user use cases + at least 1 error/misuse scenario test. Tests must run and pass.
- Non-technical work (without code): at least 1 thesis proving validity based on use cases + at least 1 antithesis (incorrect/improper usage) confuted. Cannot close if an antithesis is not confuted.
- Governance check: for significant or memory-changing closures, run
pom/skills/validate.mdto verify PROJECT_STATE, wiki, task status, decisions, and orphan artifacts.
Who verifies: when the environment supports it (sub-agents, hooks), verification should be performed by a separate agent or fresh context. When not available, the working agent re-reads files from disk instead of relying on session memory.
Exception: if verification is not possible, document the reason and close as "Complete with exceptions" (lint warning, not error).
See prompts/05-create-task-plan-from-spec.md for task creation rules and prompts/06-review-task-phase.md for review rules.
POM proposes matching namespaces for analysis, task plans, and verification evidence. For new synthesis, prefer analysis/<analysis-or-workstream>/<analysis>.md; for task plans, prefer tasks/<analysis-or-workstream>/P<priority-or-phase>/<task>.md; for cross-system verification, prefer tests/<analysis-or-workstream-or-module>/{e2e,integration,fixtures,evidence} and tests/cross-system/. When tests or evidence validate a specific analysis/workstream, reuse the same namespace, for example analysis/governance-core/..., tasks/governance-core/P0/..., and tests/governance-core/.... Existing project conventions must not be moved automatically; if the agent finds an existing structure, it must ask before changing anything.
Lint reads the tests section of pom.config.json. See prompts/05-create-task-plan-from-spec.md and prompts/06-review-task-phase.md for test planning and verification rules.
POM proposes docs/ for official documentation and src/ as the minimal source root, but existing projects should keep their real structure unless the user approves a change. Do not move documents or source files without approval.
Lint reads the documentation and source sections of pom.config.json. Existing roots such as doc/, apps/, packages/, services/, frontend/, or backend/ should be mapped there before any migration is proposed. See prompts/08-create-pom-config.md for configuration details.
| Folder | Contents |
|---|---|
WIKI_METHOD.md |
cited reference copy of the original LLM Wiki method |
prompts/ |
reusable prompts for applying the method |
skills/ |
short skill cards derived from the main POM prompts |
templates/ |
reusable templates for project state, tasks, specs, ADRs, wiki, docs, experiments, reconciliation, and the target-project updater |
scripts/ |
installer, command help, and documentation lint |
examples/ |
concrete examples of filled POM documents (ADR, PROJECT_STATE, wiki page) |
POM skills are short operational aliases for the main prompts. They do not replace prompts: they help the agent choose the correct workflow.
| Skill | Prompt |
|---|---|
help |
skill selection and explanation |
clarify |
clarify ambiguous work |
seed |
bootstrap a new project |
adopt |
adopt POM in an existing project |
pulse |
project state |
guard |
governance and lint |
plan |
task plan |
check |
review/verification |
handoff |
session closeout |
diagnose |
focused POM troubleshooting |
zero-tech-debt |
scoped end-state refactor |
challenge |
adversarial thesis/antithesis review |
config |
lint configuration |
spike |
temporary experiments |
wiki |
build, query, lightweight lint, and stale wiki maintenance |
extend |
controlled POM extension |
prune |
reduce POM method bloat |
status |
document type and status classification |
defer |
park work without implementation |
sync |
refresh or align POM in a target project |
reconcile |
resolve source/project memory divergence |
validate |
read-only governance audit |
When the agent reads a skill card, it updates pom.config.json under skillUsage with a counter and timestamp. This provides lightweight observability on which skills are actually used and how often.
{
"skillUsage": {
"wiki": { "count": 3, "lastUsed": "2026-05-01T18:30:00Z" },
"plan": { "count": 1, "lastUsed": "2026-05-01T14:00:00Z" }
}
}The schema is extensible: additional fields can be added without breaking existing entries.
The same tracking applies to canonical prompts (pom/prompts/*.md) under promptUsage. This lets you see both which skills are invoked (entry points) and which prompts are actually executed (procedures).
Use skills/extend.md when POM needs to be extended.
POM is extended by levels. First choose the smallest necessary level, avoiding turning a local adaptation into a general rule.
| Need | Where To Change |
|---|---|
| Adapt POM to a specific project | pom.config.json |
| Change governed document shape | templates/ |
| Change an agent operating procedure | prompts/ |
| Make a recurring workflow easy to invoke | skills/ |
| Automate or enforce a rule | scripts/lint-doc-governance.ts or equivalent script |
Rules:
- modify
pom.config.jsonfor project-specific folders, categories, severities, tests, wiki, docs, source, or mockups; - modify a template when the expected structure of ADRs, specs, task plans, wiki pages, docs, or manifests changes;
- add or modify a prompt when the way the agent works changes;
- add a skill only when the workflow becomes recurring and deserves a short alias;
- update lint when a rule should be verified without rereading the whole project;
- update
PROJECT_STATE.mdwhen the extension changes the operating method or restart context; - after every extension, run
npm run pom:lintwhen available.
Documentation lint is optional and project-specific. POM provides conventions and a config template, but this repository does not require every target project to install a lint runtime.
The portable lint configuration lives in:
pom/templates/POM_CONFIG_TEMPLATE.json
Each project can copy it to the repository root as:
pom.config.json
Rules:
- the POM template must remain generic and portable;
pom.config.jsoncontains project-specific rules;pom/templates/POM_CONFIG_TEMPLATE.jsonassumes POM is installed in the target project aspom/;- if POM is installed in a different path, adapt template paths before running lint;
- do not customize files directly under
pom/for a target project, because POM updates may overwrite them or create Git conflicts; - if a project needs localized or customized templates, place them outside
pom/, for example inproject-templates/ortemplates/, and pointpom.config.json.templatesto those files; - lint should use conservative defaults when the config is missing;
- if the config exists but is invalid, lint should produce clear
config-invaliderrors; - project-specific categories must live in config, not be hardcoded in the script.
Example project-specific template override:
"templates": {
"adr": "project-templates/ADR_TEMPLATE.md",
"wikiPage": "project-templates/WIKI_PAGE_TEMPLATE.md",
"projectState": "project-templates/PROJECT_STATE_TEMPLATE.md"
}With this model, pom/ remains updatable while the project's real templates stay stable and owned by the project.
Lint reads required sections (## headings) from the configured templates, not from hardcoded rules. If a project uses translated templates (e.g., ## Contesto instead of ## Context), lint automatically adapts because it reads the project's template, not the English default in pom/.
When the project uses a language other than English, translate the POM templates and place them outside pom/:
- Copy the templates you need from
pom/templates/to a project-owned folder (e.g.,project-templates/). - Translate the
##section headings and placeholder text. - Keep the same section structure — lint checks that documents contain the
##headings from the configured template. - Map the translated templates in
pom.config.json:
"templates": {
"adr": "project-templates/ADR_TEMPLATE_IT.md",
"spec": "project-templates/SPEC_TEMPLATE_IT.md",
"taskPlan": "project-templates/TASK_PLAN_TEMPLATE_IT.md"
}Lint will then check documents against the translated headings. The pom/skills/config.md workflow handles this during project configuration.
pom.config.json may include an ownership section. It tells the agent whether POM is allowed to become project governance or should stay local to the operator's work.
Allowed values:
| Mode | Meaning | Default posture |
|---|---|---|
owned |
The user can govern structure and conventions | POM may propose stronger governance when useful |
team |
The user can modify the repository, but existing conventions matter | Preserve current structure unless explicitly changed |
external_overlay |
The repository belongs to an external upstream | POM is local understanding memory only |
unknown |
Relationship not clarified yet | Ask before structural assumptions |
For existing repositories, the agent should clarify ownership before mapping POM modules. Heuristics such as a remote pointing to another organization can suggest the question, but they must not decide it silently.
For external_overlay, POM should disable governance over upstream docs/, tests, ADRs, source layout, release process, and PR contents. Use local wiki or notes to understand the project, and keep overlay artifacts out of upstream contributions unless explicitly wanted.
Installer support:
node bootstrap-pom.mjs --preset overlay
npm run pom:init -- --preset overlayThe explicit advanced form remains available:
node bootstrap-pom.mjs --profile adopt --ownership external_overlay
npm run pom:init -- --profile adopt --ownership external_overlaypom.config.json may include an adoption section. It tells the agent which POM modules are active for the project.
Allowed values:
| Key | Values |
|---|---|
profile |
minimal, wiki, decisions, full, adopt, refresh, custom |
wiki |
enabled, disabled |
decisions |
enabled, disabled |
analysis |
enabled, optional, disabled |
docs |
enabled, optional, disabled |
mockups |
enabled, disabled |
planning |
light, structured |
tasks |
light, structured |
tests |
disabled, existing, pom |
Task-plan location is configured separately under taskPlans. This keeps adoption.tasks as the planning style while allowing each project to place operational task files where they fit best.
Profile meanings:
minimal: POM operating hook, scripts, and config only;wiki: minimal + persistent wiki memory;decisions: minimal + ADR governance and generated ADR index;full: wiki + decisions + handoff memory + current planning;adopt: preserve existing structures and map POM to them;refresh: refresh installation hooks only;custom: explicit user choices.
The adoption profile is guidance for the agent and lint configuration. It must not force creation of folders that the project does not need.
Semantics:
disabledmeans POM must not create or require that module;- if a disabled module's folder already exists, lint may still check it to prevent silent decay;
optionalmeans ask before creating the module unless the current work clearly needs it;enabledmeans the module is part of the active project method and should be maintained.
POM lint may also generate derived artifacts when the rule is explicit and the generated file is not an autonomous source. Example: decisions/DECISIONS_INDEX.md is generated from ADRs and is only used for navigation/search when decisions.root keeps the default path. Generated files must declare that they should not be edited manually.
For existing projects, existing structures do not have to be moved into canonical POM folders immediately. Configure the relevant roots and patterns to map the active convention:
- decisions:
decisions.root,decisions.adrPathPattern,decisions.indexPath, anddecisions.requireTemplateSections; when onlydecisions.rootchanges, POM derives the default ADR pattern and generated index path from that root; - documentation:
documentation.officialRoot,documentation.existingRoots, and migration policy flags; - source:
source.roots,source.knownRootCandidates, and migration policy flags; - tests:
tests.root,tests.areas, optionaltests.recommendedPath, optionaltests.namespaceConvention,tests.recommendedLayout, and migration policy flags; - task plans:
taskPlans.root,taskPlans.taskPathPattern, optionaltaskPlans.recommendedPath, optionaltaskPlans.namespaceConvention,taskPlans.indexPath, and template strictness; - analysis:
analysis.root, optionalanalysis.recommendedPath, optionalanalysis.namespaceConvention, allowed dirs, and enabled/optional/disabled adoption state; - mockups and wiki: their configured roots, patterns, and enabled/optional/disabled adoption state.
Example: a project can enable decisions while keeping ADRs under doc/architecture/ADR-###-*.md. If existing documents use a legacy format, relax only the necessary checks, such as decisions.requireTemplateSections: false, while preserving or gradually improving the documents.
If generators increase or become expensive, keep them in dedicated commands rather than hiding them inside lint. The lightweight wiki reader is the exception: pom:lint refreshes it only when Markdown pages under wiki/ changed. In version 0.1.0, the commands installed in target projects are pom:init, pom:update, pom:help, pom:lint, and pom:wiki:render. The POM source repository also exposes pom:test, which runs the integration suite under tests/<area>/integration/*.mjs; this command is intentionally not propagated to target projects.
- Install POM as
pom/or copy the lint script; - copy
pom/templates/POM_CONFIG_TEMPLATE.jsonto the project root aspom.config.json; - adapt
pom.config.jsonto the real project structure; - run
node --experimental-strip-types pom/scripts/install-pom.tsor addnpm run pom:lintmanually; - run lint and fix real errors, leaving warnings as progressive adoption guidance;
- install a pre-commit hook only when the project is stable enough.
Rule: lint must remain a low-cost governance support, not a barrier to POM adoption.
In POM, templates are the normative source for document shape.
templates/
-> lint
-> real documents
When a template changes, lint should adapt by reading the required sections from the template. This avoids duplicating rules in both templates and hardcoded script logic.
Rule:
template = rule
lint = enforcement
Canonical templates:
| Template | Use |
|---|---|
ADR_TEMPLATE.md |
decision record |
AGENTS_POM_SECTION_TEMPLATE.md |
POM section for agent instruction files |
CI_GUIDE_TEMPLATE.md |
optional CI starting point (GitHub Actions, GitLab CI, CircleCI, generic shell) |
CURRENT_PLAN_TEMPLATE.md |
short roadmap and current activities |
POM_CONFIG_TEMPLATE.json |
portable documentation lint config |
EXPERIMENT_TEMPLATE.md |
versioned experiment or one-shot work |
MOCK_MANIFEST_TEMPLATE.md |
mockup package manifest |
OPEN_DISCUSSION_TEMPLATE.md |
non-authoritative desiderata, hypotheses, alternatives, and questions |
PROJECT_STATE_TEMPLATE.md |
project restart point |
TASK_PLAN_TEMPLATE.md |
verifiable task plan |
SPEC_TEMPLATE.md |
specifications |
DOC_TEMPLATE.md |
official documentation |
RECONCILIATION_TEMPLATE.md |
reconciliation between sources |
WIKI_INDEX_TEMPLATE.md |
wiki index |
WIKI_LOG_TEMPLATE.md |
chronological wiki log |
WIKI_PAGE_TEMPLATE.md |
generic wiki page |
Before creating a governed document, the agent must read and use the relevant template from pom/templates/. If a template does not fit the case, propose a template change before creating documents with a parallel structure. See the templates table above for the mapping.