Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/empty-vault/log.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
Append-only history of SecondBrain operations. This sanitized seed starts with a
single setup entry so lint can validate a fresh install cleanly.

## [2026-01-01] setup | Empty vault scaffold
## [1970-01-01] setup | Empty vault scaffold

Initialized the sanitized empty-vault example with no personal content, source material, Daily Notes, project state, or activity history.
22 changes: 19 additions & 3 deletions framework/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,19 +120,25 @@ compound across sessions.
- Valid working-note statuses are `current`, `parked`, and `reference`.
- `reference` means the note is no longer an active work item but is retained
because its reasoning, examples, or context still have value.
- Reusable operational assets such as prompt templates, checklists, method
notes, and actively used research packs remain `current` while they are still
being used or iterated. Do not treat `reference` as meaning merely
"reusable".
- Keep stable lowercase kebab-case filenames for managed working notes and
update `work/index.md` plus relevant Daily Note references when lifecycle
state or scope changes materially.
- `work/wiki-open-questions.md` remains the DTM-managed operational queue for
unresolved wiki questions and follows the same workspace conventions.
- `work/wiki-open-questions.md` is the DTM-managed operational queue for open
questions that are worth carrying beyond one day. It centralises both
unresolved wiki questions and non-wiki DTM questions so they do not remain
fragmented across Daily Notes and individual working documents.

### `documents/` — collaborative internal documents workspace

- The DTM owns collaborative drafting, revision support, and lifecycle
bookkeeping for authored internal documents such as strategies,
architectural principles, operating models, and similar work products.
- `documents/index.md` is the curated catalogue of the document workspace.
Keep every draft, final document, and managed deliverable listed exactly once
Keep every draft, final document, reference document, and managed deliverable listed exactly once
under its current stage with a one-line description concrete enough to route
future work without opening each file.
- `documents/drafts/` contains active private drafting. Agents may create and
Expand All @@ -142,6 +148,12 @@ compound across sessions.
kebab-case filenames across stages and update `documents/index.md`,
the root `log.md` when the change is materially significant, and relevant
Daily Note references in the same change.
- `documents/reference/` contains non-authored reference documents kept for
context, citation, or future drafting support. These may remain in their
original file formats and filenames. They are part of the document workspace,
not the wiki source-ingestion queue, and must never be treated as authored
canonical documents unless the user explicitly promotes or rewrites them into
`documents/drafts/` or `documents/final/`.
- `documents/deliverables/` contains shareable file-format variants of those
documents, such as `.pptx`, `.docx`, and `.xlsx`. Keep deliverables grouped
under a folder named for the document slug where practical, for example
Expand Down Expand Up @@ -183,6 +195,10 @@ compound across sessions.
success and the canonical URL and publication time are recorded.
- A failed or ambiguous publication remains in `writing/ready/`; never mark or
move it as published optimistically.
- `writing/archive/` contains retained records of formerly published pieces
that should no longer be treated as part of the active public website corpus.
Use `status: archived`, preserve the former `canonical_url` and
`published_at`, and add `archived_at` plus a concise `archive_reason`.
- Keep a stable lowercase kebab-case filename across stages. Update frontmatter,
`writing/index.md`, the root `log.md` when the change is materially
significant, and relevant Daily Note references in the same change.
Expand Down
56 changes: 39 additions & 17 deletions framework/DTM.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ Working-note statuses are:
- `parked` — inactive for now but likely to resume.
- `reference` — no longer active work, but retained because the note still has useful context or reasoning.

Reusable operational assets in `work/`, such as prompt templates, checklists, research packs, or working methods that are still being actively used or revised, should remain `current`. Do not mark a note `reference` merely because it is reusable.

Keep project filenames and managed working-note filenames in stable lowercase
kebab-case. Use `templates/project.md` for projects and
`templates/working-note.md` for new managed working notes.
Expand Down Expand Up @@ -143,6 +145,12 @@ Agents may work freely in `documents/drafts/`. Move a document to
version. These documents are not a publication queue; they are the internal
canonical record for approved work.

Use `documents/reference/` for non-authored reference documents that should
live inside the document workspace without becoming authored canonicals or wiki
sources. Keep them in their original formats where that is the point of the
reference copy, catalogue them in `documents/index.md`, and do not treat them
as drafts, finals, or deliverables.

Place shareable file-format variants such as PowerPoint, Word, and spreadsheet
files under `documents/deliverables/<document-slug>/` when they correspond to a
document workspace item. Treat the Markdown file in `documents/drafts/` or
Expand All @@ -162,6 +170,12 @@ Before creating or materially rewriting an internal document, read
from `documents/final/` as part of the approved corpus, but must never inspect
`documents/drafts/`.

If the user says they have edited a managed document directly in Obsidian or
otherwise outside the current chat, treat the on-disk file as authoritative.
Re-read that file immediately before promotion, deliverable generation, or any
final review step that depends on the latest wording. Do not rely solely on the
version already held in conversational context.

## Interaction capture

For substantive DTM work, use today's Daily Note. If none exists, run
Expand Down Expand Up @@ -262,23 +276,24 @@ entry.
note immediately; preserve the resolution in activity, a decision, project,
or wiki page as appropriate. Historical notes remain historical.

## Wiki open questions

Wiki open questions are managed separately from Daily Note open questions.

- Use `work/wiki-open-questions.md` as the operational queue for unresolved
questions still present in wiki pages.
- Refresh it with `python3 tools/wiki.py questions --write` after wiki work
changes any `## Open questions` or source `## Questions raised` section.
- Triage each item by changing its status token to `answer-myself`,
`research-with-dtm`, or `ready-to-integrate` when `needs-triage` is no longer
accurate.
- If two page-level questions are really the same underlying question, add the
same `<!-- wiki-question-thread:thread-id -->` marker to both bullets so the
queue folds them into one research thread with multiple source links. The
## Open questions

Use `work/wiki-open-questions.md` as the single operational queue for open
questions that are worth carrying beyond one day.

- Promote a Daily Note question into this queue when it is durable enough to
matter beyond one day and should be tracked without repeated carry-forward.
- Keep each queued question linked to the note or project where the answer will
eventually need integrating.
- When a question is answered, update the relevant note or project first, then
remove the question from the queue so the queue reflects the live state.
- Wiki-originated questions still require `python3 tools/wiki.py questions --write`
after wiki work changes any `## Open questions` or source `## Questions raised`
section.
- If two wiki page-level questions are really the same underlying question, add
the same `<!-- wiki-question-thread:thread-id -->` marker to both bullets so
the queue folds them into one research thread with multiple source links. The
final answer may still need integrating back into multiple wiki pages.
- When a question is answered, update the underlying wiki page first, then
refresh the queue so the question stops surfacing there.

## Day close and day open

Expand All @@ -295,7 +310,14 @@ The scheduled lifecycle runs at 00:01 in the user's local timezone. It should:
when no material progress is possible under the user's control. Track those
items under a separate `Blockers` section instead. A blocked item may appear
in `Focus` only if there is a genuine actionable step the user can take
today beyond merely waiting or monitoring.
today beyond merely waiting or monitoring. Do not mention blocked paths in a
focus item as contrast, caveat, or "do not work on this" framing; the focus
line should name only the positive action to take, and the blocked path
belongs only in `Blockers`. Each numbered focus item must cover exactly one
distinct project or task. Do not bundle unrelated work into one focus line,
even when the second item is smaller, adjacent, or non-urgent. Put that
follow-through in the appropriate to-do section unless it genuinely deserves
its own focus slot.
5. Keep the mechanically carried personal/professional tasks and open questions;
correct duplicates or categorisation errors if necessary.
6. Confirm scheduled and recurring instances are relevant for the date.
Expand Down
2 changes: 1 addition & 1 deletion framework/automation-definitions/dtm-daily-rollover.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
"schedule": "00:01 daily in the user's local timezone",
"execution_environment": "local",
"workspace": "{{VAULT_PATH}}",
"prompt": "Read AGENTS.md and DTM.md, run python3 tools/dtm.py rollover, finalise the previous note from recorded evidence, populate today's Previous Day and actionable-only Focus, keep genuine blockers in a separate Blockers section, preserve valid carried tasks and questions, instantiate recurrence, link active projects, record DTM activity, capture only concise bullet-point durable decisions in the Decisions section, log only significant durable changes, and run DTM and wiki lint checks."
"prompt": "Read AGENTS.md and DTM.md, run python3 tools/dtm.py rollover, finalise the previous note from recorded evidence, populate today's Previous Day and actionable-only Focus, keep each Focus item limited to one distinct project or task, keep Focus limited to positive actionable priorities without mentioning blocked paths as caveats or contrast clauses, keep genuine blockers in a separate Blockers section, preserve valid carried tasks and questions, instantiate recurrence, link active projects, record DTM activity, capture only concise bullet-point durable decisions in the Decisions section, log only significant durable changes, and run DTM and wiki lint checks."
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
"schedule": "02:00 daily in the user's local timezone",
"execution_environment": "local",
"workspace": "{{VAULT_PATH}}",
"prompt": "Read AGENTS.md and inspect only top-level pending files in raw/. Process each independently through the full ingestion workflow. Archive a source unchanged under raw/processed/ only after integration, index, log and lint all succeed. Leave blocked or failed sources visible and report them."
"prompt": "Read AGENTS.md and inspect only top-level pending files in raw/, ignoring metadata files such as .DS_Store. Process each independently through the full ingestion workflow. Archive a source unchanged under raw/processed/ only after integration, index, log and lint all succeed. Leave blocked or failed sources visible and report them."
}
3 changes: 2 additions & 1 deletion framework/obsidian/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
"newFileLocation": "folder",
"newFileFolderPath": "raw",
"attachmentFolderPath": "raw/assets",
"vimMode": true
"vimMode": true,
"openBehavior": "file:start-here"
}
90 changes: 90 additions & 0 deletions framework/skills/thinking-interview/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
---
name: thinking-interview
description: Conduct a structured Socratic interview that helps the user develop original thinking on a complex topic. Use only when the user invokes `$thinking-interview` or explicitly asks for a one-question-at-a-time interview to elicit, refine, and strengthen their own reasoning rather than generate ideas for them.
---

# Thinking interview

Use this skill to help the user think their way to a stronger position in their
own voice. The goal is not to supply the opinion, but to draw it out, test it,
and structure it.

## Core behavior

- Ask exactly one question at a time.
- Start broad before narrowing.
- Prefer open questions that reveal the user's current model, priorities,
assumptions, and framing.
- Use follow-up questions when reasoning is unclear, unsupported, incomplete,
internally inconsistent, or points to an important implication.
- Challenge selectively. Improve the quality of the thinking, but do not turn
the exchange into endless adversarial debate.
- Once a line of reasoning is sufficiently developed, either accept it and move
on or shift to another perspective.
- Track the user's emerging viewpoint across the interview so later questions
build on what has already been established.
- Do not answer your own questions unless the user explicitly asks you to step
out of interview mode.

## Interview flow

1. Establish the topic and any extra constraints or areas of emphasis if the
user has not already provided them.
2. Begin with a broad question that surfaces the user's overall perspective or
instinctive position.
3. Move into targeted follow-ups that clarify:
- definitions and scope;
- assumptions and implied tradeoffs;
- evidence, examples, and experience;
- consequences, risks, and second-order effects;
- points of tension, contradiction, or uncertainty;
- links between separate ideas that have emerged during the discussion.
4. Periodically maintain a working mental model of the user's position. Do this
mostly internally; only give a short recap when it helps the discussion or
the user asks for one.
5. Continue until there is enough material to reconstruct the user's opinion
confidently in their own voice, or until the user asks to stop and
synthesize.

## Question design

- Early questions should be broad, exploratory, and non-leading.
- Mid-stage questions should probe reasoning quality and reveal structure.
- Later questions should test coherence, prioritization, and implications.
- If the user gives a strong but compressed answer, unpack it rather than
moving on too quickly.
- If the user has already established a point well, avoid reopening it without
a clear reason.
- If several follow-ups are possible, choose the one most likely to improve the
user's reasoning rather than the one most likely to create argument.

## Tone

- Be calm, rigorous, and collaborative.
- Treat the user as the thinker and author.
- Avoid performative skepticism and avoid filling space with your own theories.
- If the user seems stuck, ask narrower or more concrete questions rather than
switching into idea generation.

## Completion

When the interview has reached a good stopping point, provide:

1. A concise summary of the user's position.
2. The key arguments and supporting reasoning that emerged.
3. Unresolved questions, uncertainties, or areas that would benefit from
further thought.
4. A proposed outline for an opinion piece, work note, whitepaper, or blog post
based on the discussion.
5. Any novel insights or recurring themes that emerged during the interview but
were not initially stated so explicitly.

Do not produce this synthesis prematurely. Until the interview is complete,
keep asking one question at a time.

## DTM compatibility

If this skill is invoked inside an active `$dtm` thread, remain within the DTM
workflow. Treat the interview as DTM work, capture substantive outcomes in the
Daily Note before closing out, and create or update durable notes only if the
user asks for that next step.
6 changes: 6 additions & 0 deletions framework/skills/thinking-interview/agents/openai.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
interface:
display_name: "Thinking Interview"
short_description: "One-question Socratic interview for original thinking"
default_prompt: "Use $thinking-interview to help me develop my own position on a complex topic through a one-question-at-a-time Socratic interview."
policy:
allow_implicit_invocation: false
2 changes: 2 additions & 0 deletions framework/templates/daily-note.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ tags:

## Focus

<!-- Each numbered focus item must cover one distinct project or task only. -->

## Blockers

## Personal To-Do
Expand Down
2 changes: 1 addition & 1 deletion framework/templates/working-note.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ Working material, drafts, analysis, or interim outputs.

## Next use

How this note is expected to be used next, integrated, or retired to reference status.
How this note is expected to be used next, integrated, or retired to reference status once it is no longer an active working asset.
26 changes: 24 additions & 2 deletions framework/tools/documents.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
ROOT = Path(__file__).resolve().parent.parent
DOCUMENTS = ROOT / "documents"
DELIVERABLES = DOCUMENTS / "deliverables"
REFERENCE = DOCUMENTS / "reference"
STAGES = {
"drafts": "draft",
"final": "final",
Expand Down Expand Up @@ -87,16 +88,21 @@ def lint() -> int:
for path in DELIVERABLES.rglob("*")
if path.is_file() and path.name.lower() != "readme.md" and not path.name.startswith(".")
)
reference_files = sorted(
path
for path in REFERENCE.rglob("*")
if path.is_file() and path.name.lower() != "readme.md" and not path.name.startswith(".")
)
index_path = DOCUMENTS / "index.md"
if index_path.exists():
index_text = index_path.read_text(encoding="utf-8")
index_links = [target.removesuffix(".md") for target in INDEX_ENTRY_RE.findall(index_text)]
else:
index_text = ""
index_links = []
if all_pieces or deliverable_files:
if all_pieces or deliverable_files or reference_files:
errors.append(
"documents/index.md: missing curated index; create documents/index.md before managing documents or deliverables"
"documents/index.md: missing curated index; create documents/index.md before managing documents, references, or deliverables"
)

for name, count in names.items():
Expand Down Expand Up @@ -147,6 +153,14 @@ def lint() -> int:
elif count > 1:
errors.append(f"{relative(path)}: listed {count} times in documents/index.md")

if REFERENCE.exists():
for path in reference_files:
count = index_links.count(relative(path))
if count == 0:
errors.append(f"{relative(path)}: missing from documents/index.md")
elif count > 1:
errors.append(f"{relative(path)}: listed {count} times in documents/index.md")

for item in sorted(set(errors)):
print(f"ERROR {item}")
print(f"Checked {len(all_pieces)} document(s): {len(set(errors))} error(s), 0 warning(s).")
Expand All @@ -157,6 +171,14 @@ def status() -> int:
counts = Counter(status for _, status in pieces())
print(f"Drafts: {counts['draft']}")
print(f"Final: {counts['final']}")
reference_count = sum(
1
for path in REFERENCE.rglob("*")
if path.is_file()
and path.name.lower() != "readme.md"
and not path.name.startswith(".")
)
print(f"Reference: {reference_count}")
deliverable_count = sum(
1
for path in DELIVERABLES.rglob("*")
Expand Down
Loading
Loading