Skip to content

Feat/add json file ingest#108

Merged
josealekhine merged 5 commits into
mainfrom
feat/add-json-file-ingest
May 31, 2026
Merged

Feat/add json file ingest#108
josealekhine merged 5 commits into
mainfrom
feat/add-json-file-ingest

Conversation

@josealekhine
Copy link
Copy Markdown
Member

No description provided.

Let agents persist decision/learning/task/convention entries whose
field *content* would otherwise trip a permissions.deny rule on the
literal Bash command string (e.g. a rationale describing a system
PATH install). Moving the values into a JSON file keeps them off the
command line while preserving the schema gates and INDEX maintenance
that a raw Edit into DECISIONS.md/LEARNINGS.md would bypass.

Named --json-file (not --json) because --json is a bool output-format
flag across the rest of the CLI; overloading it as a string input
path would break that convention.

Changes:
- new internal/cli/add/core/jsonpayload package: strict-decode Load
  (DisallowUnknownFields), Content (title +optional task body), and
  OverlayFlags which flags.Set's the typed fields in PreRunE
- overlay runs before the decision/learning placeholder gate, so
  JSON-supplied values are placeholder-checked too (not a bypass)
- content sourced in extract.Content ahead of --file/args/stdin
- JSON supersedes individual flags; absent fields leave CLI values
- AddConfig.JSONFile, --json-file flag + desc/yaml, errAdd.JSONParse
- integration tests on all four nouns + jsonpayload unit tests
- docs/cli/context.md and the three add skills document the escape
  hatch; spec fleshed out from stub

Phase 2 (batch array form) deferred per the spec's out-of-scope note.

Spec: specs/ctx-add-json-ingest.md
Signed-off-by: Jose Alekhinne <jose@ctx.ist>
…rning

Capture the context behind commit 5efa471: the decision to name the
add JSON-ingest flag --json-file (not --json, which is bool output
everywhere else), and the learning that new exported types must live
in types.go or TestTypeFileConvention fails.

Spec: specs/ctx-add-json-ingest.md
Signed-off-by: Jose Alekhinne <jose@ctx.ist>
Break the 472-line internal/assets/embed_test.go grab-bag into
per-concern test files (templates, project, skills, why, plugin,
schema, hooks). Test functions move verbatim — no logic change, same
18 tests, same package. embed_test.go is reduced to a breadcrumb map
pointing at the new files and the two read/-relocated tests.

The import-cycle portion of the task was already done by prior work:
nothing in package assets imports a read/ package; TestDescKeysResolve
and the default-permission tests already live in read/desc and
read/lookup. This commit finishes the "split" half — leaving better
than found rather than carrying a monolith.

Spec: specs/meta/chores.md
Signed-off-by: Jose Alekhinne <jose@ctx.ist>
Lift the unknown-subcommand handler out of the system-scoped
internal/cli/system/core/unknown into a neutral, parameterized
internal/cli/unknown package, and opt `ctx hook` in alongside
`ctx system`.

Why hook needs it: the #5 relay was scoped to `ctx system` for the
every-prompt amplification (a hooks.json-wired group whose help-dump-
at-exit-0 is read as success). But the relay's other value is making
CLI drift LOUD. `ctx hook` is consumed by name from skills and loop
scripts (ctx hook notify|event|message|pause|resume); if a verb drifts
out of the binary, the caller silently gets help + exit 0 — the agent
misreads or ignores it, and for `ctx hook notify` the human is never
notified. An unknown `ctx hook <verb>` now emits a verbatim relay box
(CLI-drift framing), best-effort fires the session-gated relay leg, and
exits non-zero. A bare `ctx hook` still prints help and exits 0.

Changes:
- internal/cli/unknown: Config + HandlerFor(cfg); SystemConfig and
  HookConfig opt-ins. handle() is the former system handler,
  parameterized. relay seam preserved for tests.
- system.Cmd / hook.Cmd both set c.RunE = unknown.HandlerFor(...).
- hook.Cmd carries AnnotationSkipInit: it is user-facing (not Hidden)
  and previously rode RootCmd's no-RunE PreRunE exemption; adding a
  RunE would newly demand an initialized context/git. The annotation
  exempts only the group-level invocation; real subcommands keep their
  preconditions. Bootstrap regression test covers this.
- hook.Hook relay label + hook-unknown.* text keys/yaml (CLI-drift copy).
- Tests moved to internal/cli/unknown; added hook routing, copy, and
  no-context-exemption coverage.

Did NOT fold into parent.Cmd (would widen every group's dependency
surface). A build-time guard scanning skills/loops for `ctx hook <verb>`
is noted out of scope.

Spec: specs/unknown-subcommand-relay-generalization.md
Signed-off-by: Jose Alekhinne <jose@ctx.ist>
The root-level .context/scratchpad-handoff.md is a one-off manual
handoff predating the /ctx-wrap-up → /ctx-handover mechanism, which
writes timestamped files under .context/handovers/. Its body still
claims "NOT YET COMMITTED … Very large diff" for work that has long
since landed, and bootstrap/status enumerate .context/*.md — so the
stale file was injected into every session start as a misleading
phantom diff. No code references it; git history preserves its
content.

Spec: specs/remove-deprecated-handoff-scratchpad.md
Signed-off-by: Jose Alekhinne <jose@ctx.ist>
@josealekhine josealekhine self-assigned this May 31, 2026
@josealekhine josealekhine merged commit ed7475e into main May 31, 2026
16 checks passed
@josealekhine josealekhine deleted the feat/add-json-file-ingest branch May 31, 2026 01:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant