okf-pro 1.0.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 (93) hide show
  1. checksums.yaml +7 -0
  2. data/.okf/contract/containment-directions.md +107 -0
  3. data/.okf/contract/exit-codes.md +42 -0
  4. data/.okf/contract/gates-only-at-the-hook-door.md +39 -0
  5. data/.okf/contract/index.md +10 -0
  6. data/.okf/contract/silent-skips.md +78 -0
  7. data/.okf/contract/telemetry-does-not-lie.md +218 -0
  8. data/.okf/contract/the-contract.md +43 -0
  9. data/.okf/design/a-comment-is-not-an-implementation.md +85 -0
  10. data/.okf/design/a-rule-you-can-walk-past.md +68 -0
  11. data/.okf/design/derivation-that-writes.md +161 -0
  12. data/.okf/design/failure-modes.md +43 -0
  13. data/.okf/design/index.md +18 -0
  14. data/.okf/design/lineage.md +95 -0
  15. data/.okf/design/structure-laws.md +46 -0
  16. data/.okf/design/the-residue.md +44 -0
  17. data/.okf/design/three-laws.md +71 -0
  18. data/.okf/design/three-pillars.md +48 -0
  19. data/.okf/index.md +31 -0
  20. data/.okf/log.md +74 -0
  21. data/.okf/scaffold/collisions-and-refusals.md +76 -0
  22. data/.okf/scaffold/index.md +8 -0
  23. data/.okf/scaffold/no-date-ships.md +41 -0
  24. data/.okf/scaffold/ownership-not-subject.md +63 -0
  25. data/.okf/scaffold/the-adopters-manual.md +114 -0
  26. data/.okf/seam/bundler-scoping.md +45 -0
  27. data/.okf/seam/identity-not-existence.md +67 -0
  28. data/.okf/seam/index.md +8 -0
  29. data/.okf/seam/the-wrapper.md +42 -0
  30. data/.okf/seam/three-fail-opens.md +44 -0
  31. data/.okf/testing/drills-over-units.md +41 -0
  32. data/.okf/testing/fixture-is-a-client.md +35 -0
  33. data/.okf/testing/index.md +4 -0
  34. data/.okf/trust/index.md +7 -0
  35. data/.okf/trust/read-owed-rule.md +45 -0
  36. data/.okf/trust/scalar-verified.md +48 -0
  37. data/CHANGELOG.md +187 -0
  38. data/LICENSE.txt +201 -0
  39. data/NOTICE +10 -0
  40. data/README.md +383 -0
  41. data/lib/okf/plugin.rb +148 -0
  42. data/lib/okf/pro/attestation.rb +62 -0
  43. data/lib/okf/pro/audit.rb +161 -0
  44. data/lib/okf/pro/board/edit.rb +201 -0
  45. data/lib/okf/pro/board.rb +291 -0
  46. data/lib/okf/pro/budget.rb +144 -0
  47. data/lib/okf/pro/bundle_root.rb +241 -0
  48. data/lib/okf/pro/cli.rb +914 -0
  49. data/lib/okf/pro/closing.rb +206 -0
  50. data/lib/okf/pro/conformance.rb +127 -0
  51. data/lib/okf/pro/conserve.rb +94 -0
  52. data/lib/okf/pro/event.rb +95 -0
  53. data/lib/okf/pro/friction.rb +262 -0
  54. data/lib/okf/pro/guards.rb +92 -0
  55. data/lib/okf/pro/log/edit.rb +68 -0
  56. data/lib/okf/pro/log.rb +162 -0
  57. data/lib/okf/pro/pairing.rb +271 -0
  58. data/lib/okf/pro/reconcile.rb +76 -0
  59. data/lib/okf/pro/records.rb +90 -0
  60. data/lib/okf/pro/scaffold.rb +258 -0
  61. data/lib/okf/pro/shell_guard.rb +164 -0
  62. data/lib/okf/pro/snapshot.rb +156 -0
  63. data/lib/okf/pro/state.rb +174 -0
  64. data/lib/okf/pro/target.rb +91 -0
  65. data/lib/okf/pro/template/gem/.claude/hooks/run +119 -0
  66. data/lib/okf/pro/template/gem/.claude/skills/okf-pro/SKILL.md +233 -0
  67. data/lib/okf/pro/template/gem/.claude/skills/okf-pro/guides/attribution.md +46 -0
  68. data/lib/okf/pro/template/gem/.claude/skills/okf-pro/guides/board.md +55 -0
  69. data/lib/okf/pro/template/gem/.claude/skills/okf-pro/guides/closing.md +21 -0
  70. data/lib/okf/pro/template/gem/.claude/skills/okf-pro/guides/frontmatter.md +73 -0
  71. data/lib/okf/pro/template/gem/.claude/skills/okf-pro/guides/okf-rules.md +25 -0
  72. data/lib/okf/pro/template/gem/.githooks/pre-commit +68 -0
  73. data/lib/okf/pro/template/gem/.github/workflows/okf-pro.yml +69 -0
  74. data/lib/okf/pro/template/seed/.claude/settings.json +24 -0
  75. data/lib/okf/pro/template/seed/.okf/areas/corpus.md +73 -0
  76. data/lib/okf/pro/template/seed/.okf/areas/index.md +6 -0
  77. data/lib/okf/pro/template/seed/.okf/board.md +21 -0
  78. data/lib/okf/pro/template/seed/.okf/glossary/index.md +13 -0
  79. data/lib/okf/pro/template/seed/.okf/index.md +30 -0
  80. data/lib/okf/pro/template/seed/.okf/journal/index.md +11 -0
  81. data/lib/okf/pro/template/seed/.okf/learnings/index.md +13 -0
  82. data/lib/okf/pro/template/seed/.okf/log.md +10 -0
  83. data/lib/okf/pro/template/seed/.okf/projects/index.md +23 -0
  84. data/lib/okf/pro/template/seed/.okf/reference/index.md +16 -0
  85. data/lib/okf/pro/template/seed/.okf/roadmap.md +33 -0
  86. data/lib/okf/pro/template/seed/.tmp/.gitkeep +0 -0
  87. data/lib/okf/pro/template/seed/CLAUDE.md +61 -0
  88. data/lib/okf/pro/template/seed/README.md +488 -0
  89. data/lib/okf/pro/template/seed/gitignore +17 -0
  90. data/lib/okf/pro/version.rb +7 -0
  91. data/lib/okf/pro/writes.rb +560 -0
  92. data/lib/okf/pro.rb +198 -0
  93. metadata +169 -0
@@ -0,0 +1,35 @@
1
+ ---
2
+ type: Learning
3
+ title: The bundle fixture is a client of the code under test
4
+ description: The bundle fixture computes its own snapshot line by calling the code under test, so a change to the counters reaches every fixture carrying a log day — which bounds what a green ported suite proves.
5
+ ---
6
+
7
+ # Why it calls the code
8
+
9
+ The fixture writes a real bundle to a temp directory: real frontmatter, real
10
+ indexes, a real board. A mock would test the mock — the checks that matter most
11
+ consult the corpus through `okf validate`, `okf lint` and `okf search`, and none
12
+ of them can be exercised against a stub without exercising the stub instead.
13
+
14
+ The log day goes further and computes its snapshot line with `Snapshot.line`,
15
+ deliberately: the stop gate verifies counters field by field, and a fixture
16
+ carrying a hand-typed line would drift from its own board exactly the way a
17
+ person's does. Tests *about* drift write their wrong line directly.
18
+
19
+ # What that costs
20
+
21
+ It makes the fixture a client. A change to the counters, or to what
22
+ [the read-owed rule](/trust/read-owed-rule.md) counts, reaches every fixture with
23
+ a log day — in the same step where a ported suite running green is supposed to be
24
+ independent proof that the port preserved behaviour.
25
+
26
+ So "the suite is green, therefore nothing changed" is only true for changes that
27
+ do not touch what the fixture calls. Where a work item does touch it, the
28
+ expected drift is stated in advance and the fixtures are updated as part of that
29
+ item — not discovered afterwards and patched until the suite agrees with itself.
30
+
31
+ # The general shape
32
+
33
+ A fixture that computes rather than states is more honest and less independent.
34
+ Both halves are real, and the useful discipline is knowing which changes cross
35
+ the line — not choosing one side permanently.
@@ -0,0 +1,4 @@
1
+ # Testing
2
+
3
+ * [drills-over-units](drills-over-units.md) - Every bug in this layer was a gate that passed when it could not do its job.
4
+ * [fixture-is-a-client](fixture-is-a-client.md) - The bundle fixture calls the code under test, so "the ported suite is unchanged proof" has a limit.
@@ -0,0 +1,7 @@
1
+ # Trust
2
+
3
+ The v0.2 vocabulary this gem's policy is written in, and the one rule four call
4
+ sites have to agree about.
5
+
6
+ * [read-owed-rule](read-owed-rule.md) - Only a human discharges the owner's read, and four sites must say so together.
7
+ * [scalar-verified](scalar-verified.md) - The grammar failure that fires the guard, gets approved, and then reads as unverified forever.
@@ -0,0 +1,45 @@
1
+ ---
2
+ type: Decision
3
+ title: A briefing is owed a read until a human has verified it
4
+ description: §5.3's trust tiers replaced a truthiness test on `verified`, and the four call sites that read the rule have to move together or a briefing falls through all of them.
5
+ ---
6
+
7
+ # The rule
8
+
9
+ ```ruby
10
+ awaiting_read? # declared_generated? && trust_tier != :human_reviewed
11
+ owner_read? # trust_tier == :human_reviewed
12
+ ```
13
+
14
+ `declared_generated?` is raw-key detection, so it separates hand-written (no
15
+ provenance at all) from v0.1-with-a-`timestamp`, which the old
16
+ `frontmatter["generated"]` test conflated with okf's own fallback.
17
+ `trust_tier` reads §5.3: no `verified` is unverified, a `process:` or agent
18
+ actor is machine-confirmed, a `human:<id>` actor is human-reviewed.
19
+
20
+ # Why all four sites move together
21
+
22
+ Two of them are exact opposites: `unverified_ids` says *the board still owes
23
+ this a To-read line*, `verified_reference_targets` says *the line can go*. Two
24
+ more read the same rule for different audiences: `Attestation.report`
25
+ corpus-wide, and the snapshot's `unverified briefings` counter.
26
+
27
+ Testing `verified` for truthiness made a nightly `process:`-verified briefing
28
+ simultaneously **awaiting the owner's read** to one caller and **verified, drop
29
+ the line** to the other. The board line vanished, and the read was never owed to
30
+ anyone again. Moving one site and not the other manufactures exactly that state,
31
+ which is why the rule is stated once, in one comment, over both predicates.
32
+
33
+ # What changed for an adopting bundle
34
+
35
+ `Snapshot.counters["unverified briefings"]` changes meaning, and the stop gate
36
+ verifies that counter field by field — so every log line in a bundle written
37
+ against the old rule goes stale on upgrade. That is a migration note, not a bug:
38
+ the counter is now answering a better question.
39
+
40
+ # The general shape
41
+
42
+ When a derived value is read by several call sites and each re-derives it from
43
+ raw fields, the sites do not drift *gradually*. They diverge the first time the
44
+ underlying vocabulary gains a case none of them was written for — and the divergence
45
+ is silent, because each site is individually correct about the field it reads.
@@ -0,0 +1,48 @@
1
+ ---
2
+ type: Finding
3
+ title: A scalar `verified:` fails in the worst available direction
4
+ description: The guard fires on the word, the owner approves, and then the reader drops the malformed value — so the concept stays unverified and the To-read line is demanded forever.
5
+ ---
6
+
7
+ # The sequence
8
+
9
+ ```yaml
10
+ verified: human:rod # a scalar; §5.2 wants a mapping or a list of them
11
+ ```
12
+
13
+ 1. `Guards.attests?` matches on the word `verified:` and routes the write to the
14
+ owner for approval. It is deliberately generous — this gate **asks**, so a
15
+ false positive costs one prompt and a miss costs a forged signature.
16
+ 2. The owner approves. From their side, the attestation happened.
17
+ 3. `Concept#verified` drops the entry, because it is not a mapping. The tier
18
+ stays `:unverified`.
19
+ 4. The To-read line is demanded forever, and the owner is told repeatedly to
20
+ read something they already read and signed.
21
+
22
+ # The fix is one line, in the right place
23
+
24
+ `okf validate` already says exactly what is wrong — *verified should be a
25
+ mapping or a list of mappings* — as a **warning**, because §9 forbids the
26
+ validator from rejecting a soft problem. `Conformance.check` read
27
+ `result.errors` only, and dropped every warning on the floor.
28
+
29
+ Surfacing `result.warnings` fixes the whole class. The alternative — a
30
+ check of our own for the trust family's grammar — would be a second parser to
31
+ keep in step with okf's, which is how the two spellings of one rule start
32
+ disagreeing.
33
+
34
+ They are surfaced as advice, not as errors: §9's separation between conformance
35
+ and curation is the kernel's, and a gate that promoted the validator's warnings
36
+ would be overruling it from outside.
37
+
38
+ It is the same failure class as [the skipped checks](/contract/silent-skips.md)
39
+ and for the same reason: a report that says "fine" over a question nobody
40
+ answered. And it lands on [the read-owed rule](/trust/read-owed-rule.md), which
41
+ is where being wrong costs the owner a demand they already discharged.
42
+
43
+ # The general shape
44
+
45
+ The most dangerous validation failure is not the one that rejects. It is the one
46
+ where a permissive *detector* and a strict *parser* disagree — the detector
47
+ fires, a human confirms, and the parser discards. Everyone downstream then has
48
+ positive evidence that the thing happened, and the stored state says it did not.
data/CHANGELOG.md ADDED
@@ -0,0 +1,187 @@
1
+ # Changelog
2
+
3
+ All notable changes to okf-pro are documented here. The format follows
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this gem uses
5
+ [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [1.0.0] - 2026-08-17
8
+
9
+ First release. okf-pro begins as a working prototype — a checker carried inside
10
+ a template repository that was cloned to start a knowledge bundle — and becomes
11
+ a gem entered through okf's plugin seam. The template is now something `okf pro
12
+ setup` writes, rather than a repository to fork.
13
+
14
+ The prototype's surface was gates and nothing else: every verb a check, a
15
+ report, or a one-time generator. Nothing answered *what is on the board* and
16
+ nothing wrote a line, so an agent working in a seeded bundle rediscovered state
17
+ by reading raw markdown and reconstructed a line's grammar from the guides on
18
+ every use. This surface answers both.
19
+
20
+ ### Added
21
+
22
+ - **`okf pro setup [DIR]`** — writes the bundle and the governance around it:
23
+ the Claude Code hooks behind a fail-closed wrapper, a `pre-commit` hook that
24
+ audits the *staged* tree, a CI workflow, the agent skill, `CLAUDE.md`, a
25
+ `README.md`, a `.gitignore`, and a blank-slate `.okf/`. It writes what it can
26
+ and never refuses wholesale: a file you already have is left alone and the
27
+ template's version is staged beside it as `<path>.okf-pro-new`. The one thing
28
+ it refuses outright is a directory that is *already* a bundle at its own root,
29
+ which writing `.okf/` beside would turn into two roots the three doors
30
+ disagree about — a bare `index.md` is a docs index, not a bundle, and is not
31
+ refused.
32
+ Both generated doors prove the checker's **identity** before trusting its exit
33
+ status: a stray `okf` on PATH that exits 0 is indistinguishable from a clean
34
+ gate, so the wrapper and the `pre-commit` hook each require the enforcer's
35
+ marker.
36
+ - **`okf pro upgrade [DIR]`** — rewrites the four files the gem owns (the hook
37
+ wrapper, the pre-commit hook, the workflow, the skill) and leaves every seeded
38
+ file byte-identical. Those four carry the contract and must track the gem;
39
+ everything else is yours from the moment it is written.
40
+ - **`okf pro hook <check>`** — one gate against one hook event on stdin.
41
+ Eight checks plus the session banner: the attestation guard, the journal
42
+ guard, the shell guard, conformance, the in-flight cap, reconciliation search,
43
+ the composed post-edit pass, and the stop gate.
44
+ - **`okf pro audit [DIR]`** — every invariant at once, for CI: the closed core,
45
+ conformance, the board's grammar, the board↔work pairing in both directions,
46
+ and the day's snapshot. It runs the linter with a clock, so nothing is
47
+ silently skipped, and confesses anything it still could not run rather than
48
+ reporting clean over it.
49
+ - **`okf pro records [DIR]`** — asks git whether the staged commit rewrites a
50
+ past journal day: a modification, a deletion, a rename or a **typechange**,
51
+ that last being how replacing a day with a symlink hides from the first
52
+ three. Records are append-only; corrections go in today's entry.
53
+ - **`okf pro snapshot [DIR]`** — computes the day's counter line and prints it.
54
+ It never writes: this is a checker, not a generator.
55
+ - **`okf pro unverified [DIR]`** — the concepts still awaiting the owner's
56
+ read, with the trust tier each one has reached.
57
+ - **`okf pro state [DIR]`** — what is on the board, in one call: every section
58
+ counter, the budget face, deadlines nothing is in flight against, the newest
59
+ logged day, whether today's journal is open, and the open projects. Cheap by
60
+ contract — it reads `board.md`, `log.md` and two globs and parses no concept.
61
+ `--full` adds the corpus-derived parts (the pairing invariants, the
62
+ attestation list, the live unverified count) behind one bundle parse.
63
+ - **`okf pro board [DIR]`** — one row per board line: section, text, the two
64
+ date shapes the counters read, age in days, and bundle links. `--section NAME`
65
+ narrows it, and a section the board does not have is exit 2 rather than an
66
+ empty answer indistinguishable from an empty section.
67
+ - **`okf pro capture "<text>"`** — a dated Inbox line, in the shape the counter
68
+ reads. Text spanning lines is refused rather than escaped.
69
+ - **`okf pro promote <selector>` / `okf pro demote <selector>`** — a line
70
+ between Backlog/Inbox and In flight, with the `In flight: k/CAP` header kept
71
+ truthful in the same write. Promotion past the cap is refused, by Rule 3. A
72
+ selector is keyed and never positional, refuses on ambiguity, and refuses a
73
+ name that names nothing: `/` and `/projects` are directories every project
74
+ sits under, and name none of them.
75
+ - **`okf pro journal open [DIR]`** — today's journal day and its index line.
76
+ What goes in the day stays yours.
77
+ - **`okf pro close <project> [DIR]`** — the three mechanical closing moves: the
78
+ marker on the project index, its board lines removed, a dated `log.md` entry.
79
+ It names the project by its directory name or by the `/projects/<slug>/` link
80
+ a board line carries, with or without the `index.md`. The fourth move —
81
+ extracting the durable part to `learnings/` — is judgment, and is reported as
82
+ owed.
83
+ - **`okf pro friction [DIR]`** — what was done by hand that a verb could do,
84
+ recorded at two points that were already wired, and grouped by the door as
85
+ well as the file: an Edit to the board says a verb went unused, a shell
86
+ redirect at anything says the trust guards were bypassed. `--issue` prints a
87
+ ready `gh issue create` against this gem's repository, and never runs it —
88
+ and prints nothing at all when nothing was recorded, rather than a report
89
+ whose body is an empty list; `--clear` resets a count that is otherwise a
90
+ lifetime total. The recorder never reports a zero it did not count — a failed
91
+ write leaves a marker, and an unwritable `.tmp/` is asked about directly. The
92
+ session banner counts the narrower thing: only rows an `okf pro` verb would
93
+ answer, because a shell redirect's answer is Edit or Write.
94
+ - **`okf pro skill <DEST>`** — the agent skill on its own, for a repository
95
+ that wants the rules without the scaffold.
96
+ - **`--json` and `--pretty`** on `state`, `board`, `snapshot`, `unverified` and
97
+ `friction`. `snapshot --json` carries the rendered line beside the twelve
98
+ counters; `unverified --json` emits structured rows rather than prose a
99
+ consumer would have to take apart with a regex.
100
+ - **The conservation guard.** Every write verb computes its new text purely,
101
+ declares the delta it intends, and is refused with exit 2 — nothing written —
102
+ if the actual delta differs, in either direction. A line dropped alongside an
103
+ append is a refusal; so is a claimed change that never happened. `close`
104
+ touches three files and decides about all of them before it writes any, so a
105
+ refusal from a later move leaves the earlier ones unwritten.
106
+ - **Preconditions the guard cannot supply.** A conservation check proves a line
107
+ was not dropped and says nothing about whether the right line was chosen, so
108
+ the choices are guarded separately: a project name is one directory segment
109
+ and never a relative path, `close` marks a first line only when it is a
110
+ markdown heading (an index carrying YAML frontmatter opens with `---`, and
111
+ appending a marker there destroys the fence while still reading as closed),
112
+ and a writer refuses a leading dash rather than committing a mistyped flag as
113
+ a board line — `--` escapes content that really starts with one.
114
+ - **The SessionStart banner is that state block**, carrying the same counters
115
+ `okf pro state` prints, the last logged Snapshot line whole and labelled by
116
+ the day it was logged under rather than as live, and a closing line saying to
117
+ refresh with `okf pro state` instead of re-reading the files. Nothing in it is
118
+ said twice: state delivered without costing a turn is still state a reader has
119
+ to get through.
120
+ - **A seeded `README.md`, written for the owner rather than the agent.**
121
+ `CLAUDE.md` and the skill both address the agent; this is the only file in the
122
+ generated tree that addresses the person, so it carries what the skill never
123
+ will — a week showing the system in use, the four habits it structures, the
124
+ tunable numbers and where they live, how to turn each gate off, what survives
125
+ removal, and what the layer does not promise. It is agent-first by
126
+ construction: the reader talks to their agent and the verbs appear in one late
127
+ section, because an owner can go a week without typing one. Seeded, not
128
+ gem-owned, so `upgrade` never touches it.
129
+ - **The skill routes to the CLI before it routes to a guide.** `SKILL.md` opens
130
+ its "What to load" section with a table of what to run instead of what to
131
+ read, and carries the canonical line shapes inline — the board bullet, the two
132
+ date grammars, the conflict line, the closure marker. The prototype named
133
+ `audit` and `unverified` only in `guides/okf-rules.md`, which the index routes
134
+ to *after* something has broken, and they went unused for exactly that reason.
135
+
136
+ ### Changed from the prototype
137
+
138
+ - **The trust policy is OKF v0.2's.** "Awaiting the owner's read" is derived
139
+ from §5.3's trust tiers rather than from a truthiness test on `verified:`.
140
+ A `human:<id>` verification discharges the read; a `process:` or agent one
141
+ makes the concept *machine-confirmed* and leaves the read owed.
142
+
143
+ **Migration:** `Snapshot`'s `unverified briefings` counter changes meaning, and
144
+ the stop gate verifies that counter field by field — so every `**Snapshot**`
145
+ line written under the old rule will be reported as disagreeing with its board.
146
+ Recompute the current day's line with `okf pro snapshot .`; past days are
147
+ records and stay as they are.
148
+
149
+ **Migration:** `verified:` must be a mapping or a list of mappings, and its
150
+ `by` must use the §7 actor convention (`human:rod`, not `rod`) to count as a
151
+ human review. A scalar `verified:` now surfaces the validator's warning
152
+ instead of being silently dropped.
153
+ - **`freshness` is removed.** `stale_after` is the format's own field and §5.5
154
+ owns where its boundary falls — a concept is stale when `today >= stale_after`,
155
+ inclusive, which is a day later than the prototype's own comparison.
156
+ `okf lint --only expired` answers the question, once, correctly.
157
+ - **The gate no longer reports clean over checks it did not run.** A default
158
+ lint skips `expired` and `stale`; the clock is now supplied so `expired` runs,
159
+ `stale` is excluded in source with its reason, and anything okf reports as
160
+ skipped in future is surfaced rather than discarded.
161
+ - **Both doors surface `okf validate`'s warnings.** They read only the errors,
162
+ so every soft finding — including a malformed trust block — was dropped. The
163
+ hook door reports them on every Edit and Write, and `okf pro audit` counts
164
+ them as findings, exactly as it already counted a linter warning: a
165
+ conformant-but-malformed `verified:` is caught at the agent's tool boundary,
166
+ and must not then be waved through by the two doors an edit made in an editor
167
+ actually passes.
168
+ - **`status: deprecated` is operative.** A reconciliation hit on a concept that
169
+ is already deprecated says so, instead of inviting the collision to be
170
+ re-litigated.
171
+ - **The shell guard no longer reads an ASCII arrow as a redirection.** `>` was
172
+ matched anywhere in a command while the comment above the pattern claimed it
173
+ was anchored to a position a redirection can occupy. Nothing implemented
174
+ that, so `grep -rn "a --> b" .okf/` — a read — was routed to the owner as a
175
+ suspected write, as was every grep for a `<!-- rule: … -->` marker or a quoted
176
+ Ruby hash. A guard that fires on reads trains the reflex that approves the one
177
+ prompt that mattered.
178
+ - **The rules stop asking for redundant conformance runs.** The PostToolUse
179
+ hook runs `okf validate` and `okf lint` in process on every Edit and Write;
180
+ `guides/okf-rules.md` says so, and asks for a manual run only when you need
181
+ the detail behind a refusal.
182
+ - **The Ruby floor is 2.4**, okf's own, down from the prototype's 2.7. This code
183
+ runs in git hooks and CI steps on machines nobody chose.
184
+ - **The `.bin/okf_pro` binary is gone.** `okf pro` is the only door, which is
185
+ what lets the wrapper refuse anything that is not it.
186
+
187
+ [1.0.0]: https://github.com/serradura/okf-gem/releases/tag/okf-pro%2Fv1.0.0
data/LICENSE.txt ADDED
@@ -0,0 +1,201 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "[]"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright 2026 Rodrigo Serradura
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
data/NOTICE ADDED
@@ -0,0 +1,10 @@
1
+ OKF gem
2
+ Copyright (c) 2026 Rodrigo Serradura
3
+
4
+ Licensed under the Apache License, Version 2.0 (see LICENSE.txt).
5
+
6
+ This product bundles the Open Knowledge Format (OKF) v0.1 specification
7
+ (lib/okf/skill/reference/SPEC.md), authored by Google Cloud Platform and
8
+ licensed under the Apache License, Version 2.0, Copyright (c) Google LLC.
9
+ Source: https://github.com/GoogleCloudPlatform/knowledge-catalog
10
+ Full license text: lib/okf/skill/reference/APACHE-2.0.txt