ctxr-cli 0.2.2 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/dist/adapter.d.ts +1 -1
  2. package/dist/adapter.d.ts.map +1 -1
  3. package/dist/adapter.js.map +1 -1
  4. package/dist/adapters/builtin/index.d.ts +1 -4
  5. package/dist/adapters/builtin/index.d.ts.map +1 -1
  6. package/dist/adapters/builtin/index.js +1 -4
  7. package/dist/adapters/builtin/index.js.map +1 -1
  8. package/dist/adapters/types.d.ts +3 -15
  9. package/dist/adapters/types.d.ts.map +1 -1
  10. package/dist/adapters/types.js +0 -1
  11. package/dist/adapters/types.js.map +1 -1
  12. package/dist/commands/adapters-generate.d.ts +3 -5
  13. package/dist/commands/adapters-generate.d.ts.map +1 -1
  14. package/dist/commands/adapters-generate.js +4 -19
  15. package/dist/commands/adapters-generate.js.map +1 -1
  16. package/dist/commands/init.d.ts.map +1 -1
  17. package/dist/commands/init.js +5 -9
  18. package/dist/commands/init.js.map +1 -1
  19. package/dist/commands/rollup-stale.d.ts.map +1 -1
  20. package/dist/commands/rollup-stale.js +1 -1
  21. package/dist/commands/rollup-stale.js.map +1 -1
  22. package/dist/commands/session-capture.d.ts +0 -1
  23. package/dist/commands/session-capture.d.ts.map +1 -1
  24. package/dist/commands/session-capture.js +33 -41
  25. package/dist/commands/session-capture.js.map +1 -1
  26. package/dist/commands/session-reap.d.ts.map +1 -1
  27. package/dist/commands/session-reap.js +4 -0
  28. package/dist/commands/session-reap.js.map +1 -1
  29. package/dist/config/defaults.d.ts +4 -4
  30. package/dist/config/defaults.d.ts.map +1 -1
  31. package/dist/config/defaults.js +4 -4
  32. package/dist/config/defaults.js.map +1 -1
  33. package/dist/config/schema.d.ts +2 -11
  34. package/dist/config/schema.d.ts.map +1 -1
  35. package/dist/config/schema.js +18 -22
  36. package/dist/config/schema.js.map +1 -1
  37. package/dist/core/agents-doc.d.ts +0 -12
  38. package/dist/core/agents-doc.d.ts.map +1 -1
  39. package/dist/core/agents-doc.js +32 -27
  40. package/dist/core/agents-doc.js.map +1 -1
  41. package/dist/core/checks/integrity-checks.d.ts +16 -0
  42. package/dist/core/checks/integrity-checks.d.ts.map +1 -1
  43. package/dist/core/checks/integrity-checks.js +108 -2
  44. package/dist/core/checks/integrity-checks.js.map +1 -1
  45. package/dist/core/checks/manifest.d.ts.map +1 -1
  46. package/dist/core/checks/manifest.js +0 -2
  47. package/dist/core/checks/manifest.js.map +1 -1
  48. package/dist/core/errors.d.ts +22 -9
  49. package/dist/core/errors.d.ts.map +1 -1
  50. package/dist/core/errors.js +30 -27
  51. package/dist/core/errors.js.map +1 -1
  52. package/dist/core/fs/fenced-region.d.ts +18 -0
  53. package/dist/core/fs/fenced-region.d.ts.map +1 -1
  54. package/dist/core/fs/fenced-region.js +60 -0
  55. package/dist/core/fs/fenced-region.js.map +1 -1
  56. package/dist/core/markers.d.ts +7 -0
  57. package/dist/core/markers.d.ts.map +1 -1
  58. package/dist/core/markers.js +9 -0
  59. package/dist/core/markers.js.map +1 -1
  60. package/dist/core/notes/list.d.ts.map +1 -1
  61. package/dist/core/notes/list.js +7 -3
  62. package/dist/core/notes/list.js.map +1 -1
  63. package/dist/core/procedures.d.ts.map +1 -1
  64. package/dist/core/procedures.js +67 -459
  65. package/dist/core/procedures.js.map +1 -1
  66. package/dist/core/reconcile.d.ts +3 -4
  67. package/dist/core/reconcile.d.ts.map +1 -1
  68. package/dist/core/reconcile.js +20 -12
  69. package/dist/core/reconcile.js.map +1 -1
  70. package/dist/core/rollup.d.ts +25 -2
  71. package/dist/core/rollup.d.ts.map +1 -1
  72. package/dist/core/rollup.js +51 -5
  73. package/dist/core/rollup.js.map +1 -1
  74. package/dist/core/write-lifecycle/path-gate.d.ts.map +1 -1
  75. package/dist/core/write-lifecycle/path-gate.js +13 -9
  76. package/dist/core/write-lifecycle/path-gate.js.map +1 -1
  77. package/dist/run.d.ts.map +1 -1
  78. package/dist/run.js +4 -43
  79. package/dist/run.js.map +1 -1
  80. package/dist/version.d.ts +1 -1
  81. package/dist/version.js +1 -1
  82. package/package.json +1 -1
  83. package/templates/skills/ctxr-connection-finding.md +15 -0
  84. package/templates/skills/ctxr-connection-proposal.md +17 -0
  85. package/templates/skills/ctxr-derived-artifacts.md +25 -0
  86. package/templates/skills/ctxr-ingest-orchestration.md +42 -0
  87. package/templates/skills/ctxr-land.md +19 -0
  88. package/templates/skills/ctxr-mission.md +36 -0
  89. package/templates/skills/ctxr-organize-audit.md +49 -0
  90. package/templates/skills/ctxr-placement.md +65 -0
  91. package/templates/skills/ctxr-rollup.md +39 -0
  92. package/templates/skills/ctxr-session-capture.md +65 -0
  93. package/templates/skills/ctxr-session-lifecycle.md +38 -0
  94. package/templates/skills/ctxr-submit.md +26 -0
  95. package/dist/commands/identity.d.ts +0 -24
  96. package/dist/commands/identity.d.ts.map +0 -1
  97. package/dist/commands/identity.js +0 -35
  98. package/dist/commands/identity.js.map +0 -1
  99. package/dist/core/checks/identity-checks.d.ts +0 -16
  100. package/dist/core/checks/identity-checks.d.ts.map +0 -1
  101. package/dist/core/checks/identity-checks.js +0 -43
  102. package/dist/core/checks/identity-checks.js.map +0 -1
  103. package/dist/core/identity.d.ts +0 -46
  104. package/dist/core/identity.d.ts.map +0 -1
  105. package/dist/core/identity.js +0 -143
  106. package/dist/core/identity.js.map +0 -1
@@ -0,0 +1,25 @@
1
+ A derived artifact is the deterministic output of a build over the store: catalog sections, the graph,
2
+ the generated AGENTS.md sections, the entry files, the owned skills, adapter outputs. They rot two ways —
3
+ stale (the source moved, the artifact did not) and clobbered (a build against the wrong base, or a hand
4
+ edit inside a fence that the next build erases).
5
+
6
+ 1. Identify the source of truth and the builder: catalog ← notes (`ctxr catalog build`); graph ← notes
7
+ (`ctxr graph build`, lives under the cache paths, never committed); AGENTS.md sections, entry files,
8
+ skills, hooks ← config + the installed package (`ctxr update`); adapter outputs ← config
9
+ (`ctxr adapters generate`).
10
+ 2. Check BEFORE you build: `ctxr catalog check` (add `--stale` for glosses whose note changed) and
11
+ `ctxr doctor`. Zero coverage, a parse error, or a count far below the store's real note count means
12
+ the builder and the base disagree — STOP; a build now writes a broken or empty artifact. Fix the base,
13
+ or hand-add only your entries, matching the committed structure, and say so in the commit message.
14
+ 3. Build, then read the result back: reported counts against the source (notes vs catalog entries, graph
15
+ nodes vs notes); your new notes present with non-zero links; nothing else lost.
16
+ 4. Fences: never hand-edit inside a `contexture:<region>` fence — the next build overwrites it. Hand
17
+ edits OUTSIDE a fence (catalog glosses, prose around a generated section) are preserved by every
18
+ build and are the right place for them. A note's own operator-defined fenced region (a ledger, a
19
+ log, any block maintained via `ctxr entry append <note> --region <name>`) is a different concern —
20
+ that append is the sanctioned write into it, never a hand edit.
21
+ 5. Commits: artifacts under the cache paths never stage. Committed derived files (the catalog) ride
22
+ their own small change AFTER the content lands, path-scoped (`git add <path>`), never swept up with
23
+ `-A` in a checkout other sessions use.
24
+ 6. Verify the remote, not the claim: after "it's merged", `git fetch origin` and
25
+ `git show origin/__DEFAULT_BRANCH__:<path> | grep -c <marker>` before treating the loop as closed.
@@ -0,0 +1,42 @@
1
+ Ingest is synthesis, not filing. The question is what the store should know after this source, not where
2
+ to put the file — "create a new note" is one option among several, never the default.
3
+
4
+ 1. Capture: write a plain markdown file directly into the inbox (see AGENTS.md's capture section) — no
5
+ provenance frontmatter; contexture assigns it at ingest.
6
+ 2. Check: run `ctxr source check <path> --source-id <id>` and read the verdict — `new`, `already_ingested`,
7
+ `drift` (same identity, the source's content moved — read what changed and decide whether to update the
8
+ note, then `ctxr source stamp <path> --id <id>` once resolved), `alternate_source_match`, or
9
+ `multiple_matches`. On `multiple_matches`, stop and resolve the ambiguity yourself; never guess which
10
+ existing note it is. A legacy note with an identity but no hash on file: `ctxr source stamp` backfills
11
+ it. A source re-published under a new URL you've confirmed is the same material:
12
+ `ctxr source add-alt <path> --id <new-id>` on the existing note, not a second ingest.
13
+ 3. Read the source fully. Then read the existing cluster BEFORE writing anything: the catalog section for
14
+ the domain (`ctxr catalog show --section <id>`), every related note in it (all of them, not one or two),
15
+ and the graph (`ctxr graph build`, then read the graph document it writes at
16
+ `.contexture/cache/graph.md` for hub notes by cluster and cross-cluster bridges; `ctxr graph query hubs`
17
+ and `ctxr graph query neighbors <path>` on the closest note for the detail). Ask: what does the
18
+ store already know, and does this source confirm, extend, contradict, or nuance it?
19
+ 4. Decide — the decision table:
20
+
21
+ | The source… | Action |
22
+ |---|---|
23
+ | adds a genuinely new concept | create a new note |
24
+ | deepens an existing note | update and expand that note |
25
+ | makes two notes redundant | merge them; fix every cross-link |
26
+ | reveals a note is badly structured | recreate it with better structure |
27
+ | belongs as a section, not a page | add a section to the existing note |
28
+ | does several of the above | do all of them |
29
+
30
+ - Hub check: if the cluster's hub already covers this, update the hub. If this source could become a
31
+ hub — a note many future notes will reference — create it at hub level, not as a leaf.
32
+ - Bridge check: if the source connects two clusters that have no bridge note, create one or add
33
+ explicit cross-links.
34
+ - Thesis-change rule: when new material contradicts a note, patch its top-level conclusion FIRST, then
35
+ hunt down the now-stale verdict language further down. A corrected body under an uncorrected
36
+ headline is worse than either alone.
37
+ - Source discipline: a field the source does not confirm is "not reported" — never inferred from
38
+ silence in either direction.
39
+ 5. Write: for a new note, `ctxr ingest <path> --source-type <type> --source-id <id>` (stamps provenance and
40
+ gives it a catalog entry). Updates to existing notes are ordinary edits that preserve prior content
41
+ (a deliberate ingest despite an `alternate_source_match` is the same command).
42
+ 6. Verify: `ctxr lint` (orphans, broken links, leftover inbox material) and `ctxr catalog check`.
@@ -0,0 +1,19 @@
1
+ The land half of the session lifecycle, after review. `ctxr-submit` is the other half; `ctxr-session-lifecycle`
2
+ covers what surrounds both and is not repeated here.
3
+
4
+ 1. Resolve the target: the current session branch by default, or name one with `--branch <name>` or
5
+ `--pr <n>`. Never run this against `__DEFAULT_BRANCH__` itself.
6
+ 2. Run `ctxr session land` (add `--yes` only when you already have explicit approval from elsewhere in
7
+ this conversation; otherwise let it prompt). It reads the pull request's state, gates the merge behind
8
+ an explicit confirmation, merges with `--merge-method` (default squash), confirms the forge reports
9
+ merged, and fast-forwards the default branch in the checkout it runs from when that checkout is on
10
+ `__DEFAULT_BRANCH__` — a checkout that cannot fast-forward is reported, never forced.
11
+ 3. Conflicting or unknown mergeability stops the command; follow `ctxr-session-lifecycle`'s conflict
12
+ playbook, then retry — a retry re-reads state and performs only what remains.
13
+ 4. Add `--reap` to remove the session worktree in the same run, once it is clean and merged; otherwise
14
+ run `ctxr session reap` afterward, or leave cleanup to whoever owns the worktree.
15
+ 5. Report exactly what the command reported — merged or not, synced or not (with why not), reaped or not
16
+ (with why not). Never claim a merge or a cleanup the command itself did not confirm.
17
+
18
+ Never merge by hand (a raw forge-CLI merge, the forge's web UI on this agent's behalf): `ctxr session land`
19
+ is the only merge path, so every landing leaves the same audit trail and passes through the same gate.
@@ -0,0 +1,36 @@
1
+ Keep this store's mission document — the standing "what's active right now" map AGENTS.md names at
2
+ `organize.mission_path` when configured — current: priorities, active builds, back burner, sunset
3
+ candidates, and debt. Hand-written content outside the fenced region is never touched.
4
+
5
+ Run `ctxr rollup stale` (or `--for <mission_path>`) first — a never-written mission document, or one whose
6
+ recorded timestamp has aged past `organize.rollup_stale_days`, is reported stale on elapsed time alone (no
7
+ backlinks compared, unlike an entity rollup); use it instead of guessing from memory whether the document
8
+ is out of date.
9
+
10
+ 1. Resolve `<mission_path>` from AGENTS.md's canonical section. If no mission document is configured for
11
+ this store, STOP — this skill has nothing to maintain; do not invent a path or create one unasked.
12
+ 2. Gather from recent work: the current session's own changes, and every store location the taxonomy
13
+ declares (read AGENTS.md's "Placing a new note" section for the configured layers) — not backlinks, and
14
+ not a sample. A priority absent from every configured layer is not a store priority; treat it as the
15
+ operator's own working memory instead and leave it out.
16
+ 3. For each active priority, state its status, its purpose, and its next useful action — a priority with no
17
+ next action is not actionable, and one with no purpose is not a priority; resolve or downgrade it rather
18
+ than carry it silently.
19
+ 4. For each back-burner item, state plainly why it is not active right now — a size cutoff, a blocking
20
+ dependency, a deliberate deprioritization. An item with no stated reason for being dormant reads as
21
+ simply forgotten; do not leave one that way.
22
+ 5. Carry sunset candidates (work whose end state is in sight or whose relevance is fading) and operational
23
+ debt (deferred cleanup, known gaps, workarounds owed a real fix) as their own sections, separate from
24
+ active and back-burner priorities — never folded into either.
25
+ 6. Synthesize into a file — bullets throughout, short clauses; skip any empty section silently (never
26
+ "N/A", "none", or "TBD"). Nothing dated later than today; no editorializing beyond the status/purpose/
27
+ next-action shape above.
28
+ 7. Write: `ctxr rollup write <mission_path> --content-file <file>` — the same command `ctxr-rollup` uses for
29
+ an entity, applied here to the store's own mission path; an idempotent fenced write (`changed: false` and
30
+ a byte-identical file when the content matches; mismatched markers abort with nothing written).
31
+
32
+ ## Report
33
+
34
+ Mission path, `changed` or unchanged, and what moved since the last write (a priority resolved, a new
35
+ back-burner addition, a sunset candidate promoted or dropped). Anything outside the fence you want to fix
36
+ is a separate, explicit edit.
@@ -0,0 +1,49 @@
1
+ 1. Run `ctxr lint` for the full health report — orphan notes, broken links, uningested inbox material,
2
+ catalog gaps. It always exits 0; its findings are observations for judgment, never a block.
3
+ 2. Run `ctxr doctor` for the invariants that DO block: catalog coverage, fail-closed visibility, hook
4
+ health, and more. Address doctor's failures before `ctxr session submit`; it runs the same checks.
5
+
6
+ ## Placement review
7
+
8
+ The diagnostic that works: "what standard am I maintaining here, and what is my review cadence?" A
9
+ location reviewed on a cadence is an ongoing responsibility; one touched only when its material is needed
10
+ is reference — whatever its label says. Apply a file-count sanity check first: dozens of reference
11
+ readings under a responsibility label is drift. Watch for topic libraries creeping back into layers
12
+ organized by actionability. Single-note calls go through `ctxr-placement`.
13
+
14
+ ## Retiring: move, don't tag
15
+
16
+ A status tag left in place defeats the layer — the active layers must show only active work.
17
+ `ctxr archive <path>` moves the note into the configured archive location as a tracked rename; the
18
+ visibility field travels unchanged (never rewrite it on the move). Retiring is reversible cold storage,
19
+ not deletion. Verify with `git status --short` showing `R` (a rename, history preserved), not a delete
20
+ plus an add, then `ctxr catalog check`.
21
+
22
+ ## Stale rollups
23
+
24
+ `ctxr lint`'s rollup-stale finding (and `ctxr rollup stale` directly) names entity notes whose backlinks
25
+ have moved since their last synthesis, or which have never been rolled up — hand each one to
26
+ `ctxr-rollup` rather than re-synthesizing ad hoc.
27
+
28
+ ## Leak scan
29
+
30
+ When a store declares context markers (`disclosure.leak_markers`), `ctxr lint` also flags content
31
+ belonging to one context found inside a note that context cannot see; `ctxr check <path> --scan` runs
32
+ the same scan on one note without needing an `--audience`. A finding names the marker context and the
33
+ matched text — read it, then move or redact the content; the scan never auto-fixes.
34
+
35
+ ## Broken links have classes — classify before fixing
36
+
37
+ - URL wrapped in wikilink syntax → convert to a markdown link.
38
+ - Basename collision (differs from an existing note only by case, hyphenation, or display name) →
39
+ rewrite with `[[Real Name|display]]` alias syntax.
40
+ - Dangling: bugs (typos, accidental self-references, a path rewrite that hit a folder name) get fixed;
41
+ healthy forward references (a name you may write about later, a planned hub) are intent markers —
42
+ leave them. Never fabricate stub notes to silence them; a one-line stub hides the real TODO and makes
43
+ orphan analysis lie.
44
+
45
+ ## Moves at scale
46
+
47
+ Two commits, never a broken intermediate: commit 1 = the moves PLUS the wikilink fixes they require;
48
+ commit 2 = tooling and doc patches. Before the moves, grep for hardcoded references to the old paths.
49
+ After they land, rebuild the derived artifacts (`ctxr-derived-artifacts`) and re-run `ctxr lint`.
@@ -0,0 +1,65 @@
1
+ Decide where a note lives BEFORE writing it, and say why: the caller wants the reasoning (which layer, why
2
+ this location over its sibling, which visibility, what would promote it) so they can push back — not a
3
+ folder name. Answer the questions in order; stop early only when the content clearly resolves.
4
+
5
+ __LAYER_STEP__
6
+
7
+ ## 2. Which location within the layer?
8
+
9
+ - Match on what the content IS. When two sibling locations both seem to fit, name the distinction between
10
+ them (abstract vs concrete; outward-facing vs inward-facing; who-we-are vs how-it-runs) and pick by
11
+ altitude and audience, not by keyword.
12
+ - Read one or two sibling notes in the chosen location and match their shape — frontmatter keys, heading
13
+ style, bullets vs prose — before writing.
14
+
15
+ ## 3. Sub-item under an existing location, or a new top-level one?
16
+
17
+ Default to a sub-item until it earns promotion. A near-empty top-level location is its own kind of
18
+ clutter — worse than a slightly crowded existing one. Starting small and promoting later is cheap;
19
+ starting big and hollow is not. Make the promotion trigger a rule, not a vibe, and write it INTO the
20
+ note: "Promote to its own top-level location the moment this holds 3+ distinct notes or topics."
21
+
22
+ ## 4. Which visibility?
23
+
24
+ Visibility is a placement input, not an afterthought, because the location sets the visibility default
25
+ (`ctxr note resolve <path>` shows the resolved value and where it came from):
26
+
27
+ - Lean on the location's default; set the visibility field in frontmatter only when you must.
28
+ - Content that bridges two contexts goes to the more restrictive one — this store fails closed to its
29
+ default context (AGENTS.md names it) whenever nothing more specific applies.
30
+ - Visibility can override location: when the visibility the content requires differs from every location
31
+ that fits topically, the topical fit loses.
32
+ - Credentials, full account numbers, and secrets never enter the store — last-4 only.
33
+
34
+ ## The collision test — "should A and B be one location?"
35
+
36
+ Before merging two locations, compare their visibility defaults (the placement section shows them). If
37
+ they differ, do NOT merge: a merged location has no safe default, every note in it needs a manual
38
+ override, and the day one is forgotten the fail-closed protection is gone — a structural guard traded for
39
+ human vigilance. If the two genuinely form one continuum with a fuzzy seam, place the boundary
40
+ deliberately and give the overlap ONE bridge note with an explicit visibility value, not a merged drawer.
41
+ A merge request often mis-detects that one side is itself mis-placed; the clean answer can be the
42
+ opposite of merging — split the mis-placed piece out and re-home it. Say so when you see it.
43
+
44
+ ## Perishable vs durable
45
+
46
+ One capture often mixes a durable fact with perishable specifics. The durable part (the reusable
47
+ structure, mechanic, or trap) goes into the permanent note. The perishable part (this period's values,
48
+ links, boilerplate) goes into a fenced `contexture:<region>` block you OVERWRITE on each refresh, never
49
+ an accumulating pile of dead entries. Do not ingest a perishable item as source material — that
50
+ manufactures an artifact for the graveyard; capture the durable slice by hand instead.
51
+
52
+ ## Wire it in
53
+
54
+ Add a one-line wikilink from the relevant hub note so the new note is not an orphan; `ctxr lint` flags
55
+ orphans and notes without a catalog entry.
56
+
57
+ ## Relocating an existing note
58
+
59
+ `ctxr archive <path>` to retire it; a plain tracked `git mv` for an ordinary re-placement. Either way the
60
+ frontmatter — including the visibility field — is left untouched.
61
+
62
+ ## Verify
63
+
64
+ `ctxr note resolve <path>` for the visibility; `ctxr lint` for orphans and catalog gaps; `ctxr doctor` for
65
+ anything that blocks a submit.
@@ -0,0 +1,39 @@
1
+ Regenerate the machine-synthesized current-state region of an entity note (a person, organization,
2
+ product, initiative, or topic hub) from every note that references it. Hand-written content outside the
3
+ fenced region is never touched.
4
+
5
+ Run `ctxr rollup stale` (or `--for <entity>` for one) to find entities worth re-rolling — it lists every
6
+ entity note whose backlinks have moved since its last synthesis, or which has never been rolled up at
7
+ all; use it instead of guessing from memory which entities are out of date.
8
+
9
+ 1. Resolve, never create. `<entity>` is a path or a note name; several candidates → list them and ask.
10
+ When a location has more than one plausible hub, prefer the shorter-named, undated one. If no entity
11
+ note exists, STOP and say so — creating it is a separate task, not a side effect of a rollup.
12
+ 2. Refuse non-entities. Dated notes, journal entries, meeting notes, generated files, and store
13
+ infrastructure are INPUTS to rollups, not entities. If the name resolves to one of those, stop and ask
14
+ which entity was meant.
15
+ 3. Gather: `ctxr rollup gather <entity>` enumerates the candidate sources (notes linking to it). Fewer
16
+ than 3 accepted sources → push back ("only N notes reference this; a rollup would be thin — continue?")
17
+ and do not auto-continue.
18
+ 4. Read EVERY accepted source, not a sample — the value of a rollup is total recall over the entity's
19
+ corpus. Per source note its date (filename, frontmatter, then mtime as a last resort), its kind, and
20
+ what it says about THIS entity specifically. For a long source, grep for the entity first.
21
+ 5. Synthesize into a file, in this shape — bullets throughout, short clauses; skip any empty subsection
22
+ silently (never "N/A", "none", or "TBD"):
23
+
24
+ ```
25
+ ## Current state
26
+ ### Status — one fact per line; what it is, what is happening now, headline problem or metric
27
+ ### Recent activity — `YYYY-MM-DD — what happened [[Source]]`, most recent first
28
+ ### Open threads — unresolved decisions, blockers, pending actions; each links where it was raised
29
+ ### Key people — `[[Person]] — role in this entity's orbit`; only people present in the corpus
30
+ ### Sources — every note consulted, sorted; the audit trail
31
+ ```
32
+
33
+ Provenance rules: every fact traceable to a source note — nothing from memory or earlier conversation;
34
+ no editorializing or recommendations; nothing dated later than today; inline `[[wikilinks]]` when one
35
+ claim has one clear source.
36
+ 6. Write: `ctxr rollup write <entity> --content-file <file>` — an idempotent fenced write (`changed: false`
37
+ and a byte-identical file when the content matches; mismatched markers abort with nothing written).
38
+ 7. Report: entity path, sources accepted, `changed` or unchanged, and notable findings (e.g. the oldest
39
+ unresolved thread). Anything outside the fence you want to fix is a separate, explicit edit.
@@ -0,0 +1,65 @@
1
+ End-of-session capture: propose what the session produced that is durable, write only what is approved.
2
+ The approval gate is what keeps the blast radius low — nothing is written without it.
3
+
4
+ ## When
5
+
6
+ Fires on the user's own closing utterance ("done", "ship it", "that's all", a sign-off) or an explicit
7
+ request. A request to open a pull request is also a wrap signal — finish the pull request first, then
8
+ propose (after the LAST one of a batch, not once per request).
9
+
10
+ Anti-triggers — stay silent when: an error, failed test, pending question, or requested follow-up is
11
+ outstanding (the session is not over); the recent turns are dominated by tuning the store or this skill
12
+ itself (nothing is capturable until that lands and gets used); the items would substantially repeat a
13
+ proposal already made this session. The agent's own summary never counts as a signal, nor does a cue
14
+ word inside quoted text, nor a request for a session summary. Zero durable items → silent; never emit
15
+ "scanned, nothing to save".
16
+
17
+ ## What is durable
18
+
19
+ Include: decisions with their rationale; net-new concepts; net-new people, organizations, or
20
+ initiatives with context; reusable patterns and playbooks; resolved non-obvious problems worth future
21
+ recall; durable preference or environment facts the user corrected you on.
22
+
23
+ Exclude: tool output, command traces, transient debugging; read-only investigation with no conclusion;
24
+ scratch work that landed on no decision.
25
+
26
+ Unsure → propose (the user can decline).
27
+
28
+ ## Proposal — ONE message, empty proposal omitted
29
+
30
+ ```
31
+ ### Store notes
32
+ - A1 path: <layer>/<location>/<Title>.md
33
+ visibility: <value> — <one-line rationale; `ctxr note resolve` on a sibling shows the default>
34
+ sketch: bullets
35
+ ```
36
+
37
+ Secret-marker pass: any item whose content looks like a credential gets `⚠ suspected-secret:` on its
38
+ own line with why (patterns worth checking: `sk-`, `ghp_`, `AKIA` + 16 chars, `Bearer …`, a JWT
39
+ `eyJ…`, a URL with a token/key/secret parameter). The marker is a hint; the user is the gate.
40
+
41
+ End with: "Approve by ID (e.g. `A1 A3`) or `skip`." An edit request → re-propose. An ambiguous
42
+ answer → do not proceed.
43
+
44
+ ## Apply
45
+
46
+ Write ONLY the approved items to a YAML proposal file, in the shape `ctxr session capture` reads:
47
+
48
+ ```yaml
49
+ notes:
50
+ - id: A1
51
+ path: <layer>/<location>/<Title>.md
52
+ mode: create # or: append
53
+ visibility: <value> # optional; omit to take the location default
54
+ body: |
55
+ matching the frontmatter and style of the sibling notes (`ctxr-placement` decides the location)
56
+ ```
57
+
58
+ Then run `ctxr session capture --proposal <file>`. It validates and writes every item independently —
59
+ one bad path never blocks the rest. These note commits ride the session pull request
60
+ (`ctxr-session-lifecycle`).
61
+
62
+ ## Report from actual writes
63
+
64
+ Report exactly what the command reported — wrote / appended / refused (with reason) / skipped, by ID —
65
+ never from the proposal itself. A refused item is surfaced prominently with its reason.
@@ -0,0 +1,38 @@
1
+ Every write lands via a session worktree and a reviewed pull request; nothing commits to the default
2
+ branch (`__DEFAULT_BRANCH__`). This skill covers what surrounds a session — starting one, re-scanning before
3
+ any plan, resolving conflicts, and sequencing several pull requests. `ctxr-submit` and `ctxr-land` are
4
+ the two verbs at the seams; their steps are not repeated here.
5
+
6
+ ## Start
7
+
8
+ `ctxr session start` creates a worktree on a fresh branch off the fetched default branch; work there.
9
+ If you find yourself on the default branch or in the root checkout, stop — `ctxr session list` shows the
10
+ active sessions to work in instead.
11
+
12
+ ## Re-scan before any plan
13
+
14
+ Re-scan whenever state may have moved under you — before presenting a plan, before running `ctxr-submit`,
15
+ after any gap in the conversation: `git fetch origin`, `git status --short`, `git diff --stat`,
16
+ `git diff --cached --stat`, `git ls-files --others --exclude-standard`,
17
+ `git log --oneline origin/__DEFAULT_BRANCH__..HEAD`. State moves under you while you work; a plan that grows
18
+ between scans is normal. Name the delta from the previous scan rather than silently folding new work into
19
+ old buckets.
20
+
21
+ ## Conflict playbook
22
+
23
+ From the session worktree: `git fetch origin && git rebase origin/__DEFAULT_BRANCH__`. For each conflicting
24
+ file inspect both sides (`git show`), understand what each represents, and produce a version that keeps
25
+ both meanings — never take one side blindly. `git add <file>`, `GIT_EDITOR=true git rebase --continue`,
26
+ then `git push --force-with-lease origin <branch>` (aborts if the remote moved underneath you). Never
27
+ resolve on the default branch.
28
+
29
+ ## Multi-PR sequencing
30
+
31
+ Parallel when the units are file-disjoint — one `ctxr session start` per unit. Sequential when files
32
+ overlap: wait for the merge (`ctxr-land`), then start the next session off the updated default branch.
33
+ Worktrees isolate directories, not logical writes: a hot file every session appends to collides at merge
34
+ time regardless — sequence those.
35
+
36
+ ## Reclaiming
37
+
38
+ __RECLAIMING_STEP__
@@ -0,0 +1,26 @@
1
+ The submit half of the session lifecycle — everything up to and including opening the pull request.
2
+ `ctxr-land` is the other half, after review; `ctxr-session-lifecycle` covers what surrounds both (starting
3
+ a session, the conflict playbook, sequencing several pull requests) and is not repeated here.
4
+
5
+ 1. Re-scan (mandatory — never replay a plan from an earlier snapshot): `git fetch origin`,
6
+ `git status --short`, `git diff --stat`, `git diff --cached --stat`,
7
+ `git ls-files --others --exclude-standard`, `git log --oneline origin/__DEFAULT_BRANCH__..HEAD`. State moves
8
+ under you while you work; name the delta from the previous scan rather than silently folding new work
9
+ into old buckets.
10
+ 2. Capture pass: run `ctxr-session-capture` exactly once here — closing a session is itself a capture
11
+ trigger; do not fire it again after submitting.
12
+ 3. Stage surgically: `git add <paths>`, never `git add -A`; confirm with `git status --short` that the
13
+ staged set matches the intended unit. Derived artifacts under the cache paths never stage.
14
+ 4. One coherent unit per pull request. If the session produced two disjoint units, say so and ask
15
+ whether to split.
16
+ 5. Fire gate: `ctxr session submit` commits, pushes, and opens the pull request — an external side
17
+ effect, and plan consent is not fire consent. Present the branch, the title, and what rides it; wait
18
+ for an explicit go before running it.
19
+ 6. Run: `ctxr session submit --branch "<name>" --title "<title>" --body "<why / what changed /
20
+ verification / follow-ups>"`. Name a real branch with `--branch` — never let a generated name reach
21
+ the forge. It runs the full store validation first; fix a failure, never bypass it. If no forge is
22
+ reachable it still pushes and prints the manual pull-request instructions.
23
+ 7. Verify before any retry: a transport error can arrive AFTER the push or the pull-request open already
24
+ succeeded. Before retrying anything, `git ls-remote origin <branch>` and the forge's pull-request list
25
+ for the branch — never replay a push or a pull-request open blindly.
26
+ 8. Hand off: report the pull request, then point at `ctxr-land` for after review.
@@ -1,24 +0,0 @@
1
- import type { CommandOutcome, CommandRequires } from '../core/command.js';
2
- import type { Store } from '../core/store.js';
3
- export declare const requires: CommandRequires;
4
- export interface IdentityEditData {
5
- path: string;
6
- entries: number;
7
- }
8
- export interface IdentityAddFlags {
9
- file: string;
10
- text: string;
11
- }
12
- export declare function executeAdd(store: Store, flags: IdentityAddFlags): Promise<CommandOutcome<IdentityEditData>>;
13
- export interface IdentityReplaceFlags {
14
- file: string;
15
- match: string;
16
- text: string;
17
- }
18
- export declare function executeReplace(store: Store, flags: IdentityReplaceFlags): Promise<CommandOutcome<IdentityEditData>>;
19
- export interface IdentityRemoveFlags {
20
- file: string;
21
- match: string;
22
- }
23
- export declare function executeRemove(store: Store, flags: IdentityRemoveFlags): Promise<CommandOutcome<IdentityEditData>>;
24
- //# sourceMappingURL=identity.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/commands/identity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAU1E,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAE9C,eAAO,MAAM,QAAQ,EAAE,eAAuC,CAAC;AAE/D,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAmBD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAsB,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,cAAc,CAAC,gBAAgB,CAAC,CAAC,CAIjH;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAsB,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,cAAc,CAAC,gBAAgB,CAAC,CAAC,CAIzH;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,cAAc,CAAC,gBAAgB,CAAC,CAAC,CAIvH"}
@@ -1,35 +0,0 @@
1
- import { ExitCode } from '../core/exit-codes.js';
2
- import { UnknownIdentityRoleError } from '../core/errors.js';
3
- import { addIdentityEntry, IDENTITY_ROLES, removeIdentityEntry, replaceIdentityEntry, } from '../core/identity.js';
4
- export const requires = { store: 'required' };
5
- function checkRole(role) {
6
- if (!IDENTITY_ROLES.includes(role)) {
7
- throw new UnknownIdentityRoleError(role, IDENTITY_ROLES);
8
- }
9
- }
10
- function outcome(store, result, humanSummary) {
11
- return {
12
- exitCode: ExitCode.Ok,
13
- data: result,
14
- findings: [],
15
- humanSummary,
16
- storeRoot: store.root,
17
- schemaVersion: store.config.schema_version,
18
- };
19
- }
20
- export async function executeAdd(store, flags) {
21
- checkRole(flags.file);
22
- const result = await addIdentityEntry(store.root, store.config, flags.file, flags.text);
23
- return outcome(store, result, `Added an entry to "${result.path}" (${result.entries} total).`);
24
- }
25
- export async function executeReplace(store, flags) {
26
- checkRole(flags.file);
27
- const result = await replaceIdentityEntry(store.root, store.config, flags.file, flags.match, flags.text);
28
- return outcome(store, result, `Replaced the entry matching "${flags.match}" in "${result.path}" (${result.entries} total).`);
29
- }
30
- export async function executeRemove(store, flags) {
31
- checkRole(flags.file);
32
- const result = await removeIdentityEntry(store.root, store.config, flags.file, flags.match);
33
- return outcome(store, result, `Removed the entry matching "${flags.match}" from "${result.path}" (${result.entries} total).`);
34
- }
35
- //# sourceMappingURL=identity.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/commands/identity.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,mBAAmB,EACnB,oBAAoB,GAErB,MAAM,qBAAqB,CAAC;AAG7B,MAAM,CAAC,MAAM,QAAQ,GAAoB,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;AAO/D,SAAS,SAAS,CAAC,IAAY;IAC7B,IAAI,CAAE,cAAoC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1D,MAAM,IAAI,wBAAwB,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;IAC3D,CAAC;AACH,CAAC;AAED,SAAS,OAAO,CAAC,KAAY,EAAE,MAAyC,EAAE,YAAoB;IAC5F,OAAO;QACL,QAAQ,EAAE,QAAQ,CAAC,EAAE;QACrB,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,EAAE;QACZ,YAAY;QACZ,SAAS,EAAE,KAAK,CAAC,IAAI;QACrB,aAAa,EAAE,KAAK,CAAC,MAAM,CAAC,cAAc;KAC3C,CAAC;AACJ,CAAC;AAOD,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,KAAY,EAAE,KAAuB;IACpE,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACtB,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;IACxF,OAAO,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,sBAAsB,MAAM,CAAC,IAAI,MAAM,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AACjG,CAAC;AAQD,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,KAAY,EAAE,KAA2B;IAC5E,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACtB,MAAM,MAAM,GAAG,MAAM,oBAAoB,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;IACzG,OAAO,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,gCAAgC,KAAK,CAAC,KAAK,SAAS,MAAM,CAAC,IAAI,MAAM,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAC/H,CAAC;AAOD,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,KAAY,EAAE,KAA0B;IAC1E,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACtB,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;IAC5F,OAAO,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,+BAA+B,KAAK,CAAC,KAAK,WAAW,MAAM,CAAC,IAAI,MAAM,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAChI,CAAC"}
@@ -1,16 +0,0 @@
1
- /**
2
- * agent-identity spec: "Identity files... SHALL live under a path declared
3
- * in the store's retrieval exclusion configuration." Catalog and graph
4
- * already can't surface anything under an excluded prefix (they're both
5
- * built from listNotes()) — this check guards the one way that guarantee
6
- * could quietly break: an operator editing config.retrieval.exclude_paths
7
- * and dropping an identity path from it.
8
- *
9
- * session-capture-command spec (D3): checked against each ROLE'S RESOLVED
10
- * path — not the identity directory alone — so a role relocated outside
11
- * `identity.path` (e.g. into a directory a harness runtime links into)
12
- * still cannot leak into retrieval.
13
- */
14
- export declare const identityExclusionCheck: import("./types.js").CheckDefinition;
15
- export declare const IDENTITY_CHECKS: import("./types.js").CheckDefinition[];
16
- //# sourceMappingURL=identity-checks.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"identity-checks.d.ts","sourceRoot":"","sources":["../../../src/core/checks/identity-checks.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,sBAAsB,sCAyBjC,CAAC;AAEH,eAAO,MAAM,eAAe,wCAA2B,CAAC"}
@@ -1,43 +0,0 @@
1
- import { IDENTITY_ROLES, identityFilePath } from '../identity.js';
2
- import { defineCheck } from './types.js';
3
- /**
4
- * agent-identity spec: "Identity files... SHALL live under a path declared
5
- * in the store's retrieval exclusion configuration." Catalog and graph
6
- * already can't surface anything under an excluded prefix (they're both
7
- * built from listNotes()) — this check guards the one way that guarantee
8
- * could quietly break: an operator editing config.retrieval.exclude_paths
9
- * and dropping an identity path from it.
10
- *
11
- * session-capture-command spec (D3): checked against each ROLE'S RESOLVED
12
- * path — not the identity directory alone — so a role relocated outside
13
- * `identity.path` (e.g. into a directory a harness runtime links into)
14
- * still cannot leak into retrieval.
15
- */
16
- export const identityExclusionCheck = defineCheck({
17
- id: 'identity.excluded_from_retrieval',
18
- title: 'Every identity role\'s resolved path is excluded from retrieval',
19
- severity: 'invariant',
20
- capability: 'agent-identity',
21
- scopes: ['store'],
22
- async run(ctx) {
23
- const findings = [];
24
- for (const role of IDENTITY_ROLES) {
25
- const resolvedPath = identityFilePath(ctx.config, role);
26
- const covered = ctx.config.retrieval.exclude_paths.some((prefix) => {
27
- const trimmed = prefix.replace(/\/+$/, '');
28
- return resolvedPath === trimmed || resolvedPath.startsWith(`${trimmed}/`);
29
- });
30
- if (!covered) {
31
- findings.push({
32
- code: 'identity.not_excluded',
33
- severity: 'error',
34
- message: `The ${role} identity file "${resolvedPath}" is not covered by retrieval.exclude_paths — it could leak into the catalog or graph.`,
35
- subject: resolvedPath,
36
- });
37
- }
38
- }
39
- return { status: findings.length > 0 ? 'fail' : 'pass', findings };
40
- },
41
- });
42
- export const IDENTITY_CHECKS = [identityExclusionCheck];
43
- //# sourceMappingURL=identity-checks.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"identity-checks.js","sourceRoot":"","sources":["../../../src/core/checks/identity-checks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAGzC;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,WAAW,CAAC;IAChD,EAAE,EAAE,kCAAkC;IACtC,KAAK,EAAE,iEAAiE;IACxE,QAAQ,EAAE,WAAW;IACrB,UAAU,EAAE,gBAAgB;IAC5B,MAAM,EAAE,CAAC,OAAO,CAAC;IACjB,KAAK,CAAC,GAAG,CAAC,GAAG;QACX,MAAM,QAAQ,GAAc,EAAE,CAAC;QAC/B,KAAK,MAAM,IAAI,IAAI,cAAc,EAAE,CAAC;YAClC,MAAM,YAAY,GAAG,gBAAgB,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YACxD,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;gBACjE,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;gBAC3C,OAAO,YAAY,KAAK,OAAO,IAAI,YAAY,CAAC,UAAU,CAAC,GAAG,OAAO,GAAG,CAAC,CAAC;YAC5E,CAAC,CAAC,CAAC;YACH,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,QAAQ,CAAC,IAAI,CAAC;oBACZ,IAAI,EAAE,uBAAuB;oBAC7B,QAAQ,EAAE,OAAO;oBACjB,OAAO,EAAE,OAAO,IAAI,mBAAmB,YAAY,wFAAwF;oBAC3I,OAAO,EAAE,YAAY;iBACtB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QACD,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC;IACrE,CAAC;CACF,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,sBAAsB,CAAC,CAAC"}
@@ -1,46 +0,0 @@
1
- import type { StoreConfig } from '../config/schema.js';
2
- /**
3
- * agent-identity spec: three canonical, harness-neutral roles — posture,
4
- * durable world facts, durable user facts — kept distinct from retrievable
5
- * knowledge (excluded from every retrieval leg via each resolved path being
6
- * covered by config.retrieval.exclude_paths). A harness's own
7
- * identity-injection adapter decides how these reach a running agent; core
8
- * never reads their content itself.
9
- *
10
- * session-capture-command spec (D3): a role's path is CONFIGURABLE
11
- * (`identity.files`) — a store whose runtime keeps its memory elsewhere
12
- * points the role there, and every consumer below resolves through
13
- * `identityFilePath`/`identityFilePaths` rather than assuming the canonical
14
- * layout, so the relocated file IS the mechanism, not a copy of it.
15
- */
16
- export declare const IDENTITY_ROLES: readonly ['posture', 'world-facts', 'user-facts'];
17
- export type IdentityRole = (typeof IDENTITY_ROLES)[number];
18
- /** The canonical filename each role resolves to under `identity.path` when no override is configured. */
19
- export declare const IDENTITY_FILES: Record<IdentityRole, string>;
20
- /** The store-relative path this role resolves to: its configured binding, or its canonical file under `identity.path`. */
21
- export declare function identityFilePath(config: StoreConfig, role: IdentityRole): string;
22
- export declare function identityFilePaths(config: StoreConfig): string[];
23
- /** Creates any of the three canonical identity files that don't exist yet — never overwrites an existing one. */
24
- export declare function ensureIdentityFiles(root: string, config: StoreConfig): Promise<string[]>;
25
- /**
26
- * session-capture-command spec (D4): an entry is the text between two
27
- * delimiter lines. The default delimiter ('') means an empty (blank) line,
28
- * so paragraphs are entries and a heading-sectioned file's headings simply
29
- * become part of the entry that follows them — no section vocabulary, no
30
- * format detection.
31
- */
32
- export declare function splitEntries(text: string, delimiter: string): string[];
33
- export declare function joinEntries(entries: readonly string[], delimiter: string): string;
34
- export interface IdentityEntryResult {
35
- /** The role's resolved, store-relative path. */
36
- path: string;
37
- /** The entry count after the edit. */
38
- entries: number;
39
- }
40
- /** Appends a new entry at the end of the role's file, creating it (with no other entries) if it doesn't exist yet. */
41
- export declare function addIdentityEntry(root: string, config: StoreConfig, role: IdentityRole, text: string): Promise<IdentityEntryResult>;
42
- /** Replaces the single entry containing `match`; refuses, writing nothing, when zero or several entries match. */
43
- export declare function replaceIdentityEntry(root: string, config: StoreConfig, role: IdentityRole, match: string, text: string): Promise<IdentityEntryResult>;
44
- /** Removes the single entry containing `match`; refuses, writing nothing, when zero or several entries match. */
45
- export declare function removeIdentityEntry(root: string, config: StoreConfig, role: IdentityRole, match: string): Promise<IdentityEntryResult>;
46
- //# sourceMappingURL=identity.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/core/identity.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAIvD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,cAAc,YAAI,SAAS,EAAE,aAAa,EAAE,YAAY,CAAU,CAAC;AAChF,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAE3D,yGAAyG;AACzG,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAIvD,CAAC;AAQF,0HAA0H;AAC1H,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,YAAY,GAAG,MAAM,CAIhF;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,EAAE,CAE/D;AAED,iHAAiH;AACjH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAY9F;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAmBtE;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAIjF;AAwBD,MAAM,WAAW,mBAAmB;IAClC,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,sCAAsC;IACtC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,sHAAsH;AACtH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAQxI;AAED,kHAAkH;AAClH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,WAAW,EACnB,IAAI,EAAE,YAAY,EAClB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,mBAAmB,CAAC,CAQ9B;AAED,iHAAiH;AACjH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,WAAW,EACnB,IAAI,EAAE,YAAY,EAClB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,mBAAmB,CAAC,CAQ9B"}